Skip to content

UI fixes and copy to clipboard#4

Open
ashishdevdocs wants to merge 2 commits into
mainfrom
styling-fixes
Open

UI fixes and copy to clipboard#4
ashishdevdocs wants to merge 2 commits into
mainfrom
styling-fixes

Conversation

@ashishdevdocs
Copy link
Copy Markdown
Collaborator

@ashishdevdocs ashishdevdocs commented Apr 3, 2024

Summary by CodeRabbit

  • New Features

    • Added copy-to-clipboard functionality for answer content with a configurable enable/disable option (disabled by default).
  • Style

    • Refined spacing, padding, and layout throughout the answer interface for improved visual consistency.

Review Change Stack

@Wentzel-DevDocs
Copy link
Copy Markdown
Contributor

Autonomous SOC2 cleanup disposition (2026-05-24): still potentially useful, but not merge-ready as-is; not superseded by WENTZEL #12-#15.

This is unrelated UI/copy-to-clipboard work: CSS spacing changes plus prompt.allowCopy / useCopyToClipboard wiring. The WENTZEL SOC2 PRs do not cover this feature.

Current state: open since 2024-04-03, last updated 2025-01-13, clean merge state, no PR checks reported, 5 changed files across shared CSS, prompt, headless primitives, and types.

Blockers before merge: stale product/UI assumptions, no current CI signal, and shared styling/API surface area. Recommendation is not to merge directly; harvest into a fresh WENTZEL branch only if product still wants the feature. No replacement branch created.

PromptView's new allowCopy button passes the answer as a plain string
child, but CopyCodeButton read children[0].props.children[0] — which on
a string is just its first character's (undefined) props — so the answer-
copy button copied an empty string. Add extractCopyableText() to handle
both the plain-string answer shape and the react-markdown code-block tree.

Add headless tests covering both child shapes and the useCopyToClipboard
didCopy toggle; the plain-string test fails against the old extraction
and passes with the fix.

Local: build green; headless suite 17/17; full suite 146 (3 added). The
intermittent SearchView keyboard-nav flake on this branch is pre-existing
on its older base and unrelated (fixed separately on the eslint-9 branch).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

This PR introduces a configurable copy-to-clipboard feature for generated answers in DevDocs.ai. It adds a new allowCopy option to the prompt configuration, implements a reusable clipboard hook, integrates the copy button into answer rendering, covers the functionality with tests, and refines UI spacing throughout the stylesheet.

Changes

Copy-to-clipboard feature

Layer / File(s) Summary
Type contract and default configuration
packages/react/src/types.ts, packages/react/src/constants.tsx
Introduces prompt.allowCopy?: boolean option and sets default to false.
Copy hook and button implementation
packages/react/src/primitives/headless.tsx
Implements useCopyToClipboard hook to manage clipboard writes and didCopy state; updates CopyCodeButton to robustly extract text from plain strings and nested markdown code-block elements; exports the new hook.
PromptView component integration
packages/react/src/prompt/PromptView.tsx
Passes resolved promptOptions to AnswerContainer; conditionally renders CopyCodeButton when allowCopy is enabled and state is 'done'.
Clipboard behavior testing
packages/react/src/primitives/headless.test.tsx
Adds clipboard mock isolation, mockClipboard() helper, and three tests verifying copy behavior for plain strings, markdown code blocks, and hook state toggling.
Visual spacing and copy button styling
packages/css/devdocsai.css
Tightens prompt wrapper spacing, refines answer typography/padding and list layouts, reduces caret and feedback action margins, adds copy-button styling inside copy container, and adjusts reference section spacing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A clipboard whisper, so clean and so bright,
Copy-to-clipboard, a feature so right!
With hooks and with buttons, the answers take flight,
Tighter padding now makes the spacing just right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'UI fixes and copy to clipboard' directly addresses both main aspects of the changeset: CSS styling adjustments and the new copy-to-clipboard functionality wiring.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch styling-fixes

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/css/devdocsai.css

Parsing error: Declaration or statement expected.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/react/src/primitives/headless.tsx`:
- Around line 275-280: The handleClick in useCopyToClipboard currently calls
navigator.clipboard.writeText(content) without feature-detecting or awaiting it
and immediately toggles setDidCopy(true); change handleClick to first check for
navigator.clipboard existence, then call writeText as an async operation (or
handle the returned promise), await it or use .then/.catch, only call
setDidCopy(true) and start the 2000ms reset timer on successful resolution, and
handle rejection by logging or exposing an error state so unhandled promise
rejections and false "copied" UI are avoided.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d74b8d52-bf7e-40a2-aaca-077d1a66d197

📥 Commits

Reviewing files that changed from the base of the PR and between 87e1ae2 and 74c9cc9.

📒 Files selected for processing (6)
  • packages/css/devdocsai.css
  • packages/react/src/constants.tsx
  • packages/react/src/primitives/headless.test.tsx
  • packages/react/src/primitives/headless.tsx
  • packages/react/src/prompt/PromptView.tsx
  • packages/react/src/types.ts

Comment on lines 275 to 280
const handleClick = (): void => {
navigator.clipboard.writeText(props.children[0]?.props.children[0]);
navigator.clipboard.writeText(content);
setDidCopy(true);
setTimeout(() => {
setDidCopy(false);
}, 2000);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the copy path has no availability/rejection handling today.
rg -n "navigator\.clipboard|writeText|setDidCopy|setTimeout" packages/react/src/primitives/headless.tsx

Repository: devdocsorg/devdocsai-js

Length of output: 256


🏁 Script executed:

#!/bin/bash
# Inspect the surrounding implementation for any guard/try-catch/promise handling.
sed -n '250,310p' packages/react/src/primitives/headless.tsx | nl -ba

Repository: devdocsorg/devdocsai-js

Length of output: 110


🏁 Script executed:

#!/bin/bash
# Re-run with line numbers using cat -n (no nl available).
sed -n '250,310p' packages/react/src/primitives/headless.tsx | cat -n

Repository: devdocsorg/devdocsai-js

Length of output: 2372


Guard Clipboard API failures before flipping didCopy.

useCopyToClipboard calls navigator.clipboard.writeText(content) without checking API availability or handling promise rejection, but immediately sets setDidCopy(true)—so unsupported/rejected cases can show “copied” UI and may produce unhandled promise rejections.

Suggested patch
   const handleClick = (): void => {
-    navigator.clipboard.writeText(content);
-    setDidCopy(true);
-    setTimeout(() => {
-      setDidCopy(false);
-    }, 2000);
+    if (!navigator.clipboard?.writeText) return;
+    void navigator.clipboard
+      .writeText(content)
+      .then(() => {
+        setDidCopy(true);
+        setTimeout(() => {
+          setDidCopy(false);
+        }, 2000);
+      })
+      .catch(() => {
+        setDidCopy(false);
+      });
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleClick = (): void => {
navigator.clipboard.writeText(props.children[0]?.props.children[0]);
navigator.clipboard.writeText(content);
setDidCopy(true);
setTimeout(() => {
setDidCopy(false);
}, 2000);
const handleClick = (): void => {
if (!navigator.clipboard?.writeText) return;
void navigator.clipboard
.writeText(content)
.then(() => {
setDidCopy(true);
setTimeout(() => {
setDidCopy(false);
}, 2000);
})
.catch(() => {
setDidCopy(false);
});
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react/src/primitives/headless.tsx` around lines 275 - 280, The
handleClick in useCopyToClipboard currently calls
navigator.clipboard.writeText(content) without feature-detecting or awaiting it
and immediately toggles setDidCopy(true); change handleClick to first check for
navigator.clipboard existence, then call writeText as an async operation (or
handle the returned promise), await it or use .then/.catch, only call
setDidCopy(true) and start the 2000ms reset timer on successful resolution, and
handle rejection by logging or exposing an error state so unhandled promise
rejections and false "copied" UI are avoided.

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