Skip to content

feat: add 'Use with LLM' dropdown to doc pages#597

Open
data-cowwboy wants to merge 4 commits intomainfrom
feat/llm-actions-dropdown
Open

feat: add 'Use with LLM' dropdown to doc pages#597
data-cowwboy wants to merge 4 commits intomainfrom
feat/llm-actions-dropdown

Conversation

@data-cowwboy
Copy link
Contributor

@data-cowwboy data-cowwboy commented Feb 27, 2026

Summary

  • Adds a "Use with LLM" dropdown button to every doc page
  • Open in ChatGPT — opens ChatGPT with prompt to read the current page URL
  • Open in Claude — opens Claude with prompt to read the current page URL
  • Copy page — fetches raw markdown from GitHub and copies to clipboard
  • View as Markdown — opens the raw markdown source in a new tab
  • Supports both light and dark mode

Implementation

  • New component: src/components/AiActionsDropdown/
  • Swizzled DocItem/Layout to inject the dropdown on all doc pages
  • Uses the existing editUrl config to derive raw GitHub URLs

Test plan

  • Run yarn start and verify dropdown appears on doc pages
  • Verify "Open in ChatGPT" and "Open in Claude" open correct URLs with page context
  • Verify "Copy page" copies raw markdown to clipboard
  • Verify "View as Markdown" opens raw GitHub file
  • Check light and dark mode styling

Summary by CodeRabbit

  • New Features
    • Added "Use with LLM" dropdown menu on documentation pages
      • Open current page in ChatGPT or Claude for AI-assisted discussions
      • Copy page content to clipboard with one click
      • View page as raw Markdown in a new tab

@data-cowwboy data-cowwboy requested a review from a team as a code owner February 27, 2026 07:08
@vercel
Copy link

vercel bot commented Feb 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Feb 27, 2026 10:47am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new "Use with LLM" dropdown component that provides four AI-related actions (ChatGPT, Claude, copy page, view markdown) within documentation pages. The component includes state management for dropdown visibility and copy feedback, with fallback handling for fetch errors. Integration into the doc item layout adds the dropdown alongside synthetic titles when available.

Changes

Cohort / File(s) Summary
AI Actions Dropdown Component
src/components/AiActionsDropdown/index.tsx, src/components/AiActionsDropdown/styles.module.css
New React component providing LLM integration actions with dropdown toggle, external link handlers (ChatGPT/Claude), copy-to-clipboard with fetch + fallback fallback for article text, and markdown view navigation. Manages open/close state via mousedown listener and copy feedback via timed state. Includes complete styling with dark theme support, hover effects, and inline SVG icons.
Doc Item Integration
src/theme/DocItem/Content/index.tsx
Wraps doc content to derive synthetic title from metadata and render AiActionsDropdown alongside or below the title. Uses useDoc hook to access editUrl for markdown view feature and integrates dropdown into doc header layout.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With whiskers twitching bright and keen,
We hop through docs with ChatGPT's sheen,
Copy, fetch, and fallback too,
Markdown views for me and you! 📚✨

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main feature addition: a 'Use with LLM' dropdown on doc pages, which matches the primary change in the changeset.
Description check ✅ Passed The description provides a clear summary, implementation details, and a comprehensive test plan, addressing the intent and scope of the PR, though it doesn't strictly follow the template sections.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/llm-actions-dropdown

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.

❤️ Share

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

Adds a dropdown button on every doc page with options to open the page
in ChatGPT or Claude, copy the raw markdown source to clipboard, and
view the page as plain markdown via GitHub raw URL.
- Fix button colors for dark mode (light blue bg, dark text)
- Use correct logo SVG for the AI assistant option
- Update LLM prompt to "Read from <url> so I can ask questions about it"
- Fetch raw markdown from GitHub for copy/view actions
Copy link
Contributor

@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: 2

🧹 Nitpick comments (2)
src/components/AiActionsDropdown/index.tsx (1)

76-77: Consider handling the case when editUrl is not available.

When rawUrl is falsy (no editUrl provided), clicking "Copy page" closes the dropdown without any feedback. Consider either:

  1. Using the fallback (copy article text) when rawUrl is unavailable, or
  2. Disabling the copy button when editUrl is not provided
♻️ Option 1: Always attempt fallback when rawUrl unavailable
   const copyPage = async () => {
-    if (rawUrl) {
-      try {
-        const res = await fetch(rawUrl)
-        const md = await res.text()
+    try {
+      if (rawUrl) {
+        const res = await fetch(rawUrl)
+        if (!res.ok) throw new Error(`HTTP ${res.status}`)
+        const md = await res.text()
         await navigator.clipboard.writeText(md)
-        setCopied(true)
-        setTimeout(() => setCopied(false), 2000)
-      } catch {
-        // Fallback: copy article text if fetch fails
+      } else {
         const article = document.querySelector('article')
-        if (article) {
-          await navigator.clipboard.writeText(article.innerText)
-          setCopied(true)
-          setTimeout(() => setCopied(false), 2000)
-        }
+        if (article) await navigator.clipboard.writeText(article.innerText)
       }
+      setCopied(true)
+      setTimeout(() => setCopied(false), 2000)
+    } catch {
+      // Fallback: copy article text if fetch fails
+      const article = document.querySelector('article')
+      if (article) {
+        await navigator.clipboard.writeText(article.innerText)
+        setCopied(true)
+        setTimeout(() => setCopied(false), 2000)
+      }
     }
     setOpen(false)
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/AiActionsDropdown/index.tsx` around lines 76 - 77, The
copyPage handler currently assumes rawUrl/editUrl exists and silently closes the
dropdown when missing; update the copyPage function to first check rawUrl
(and/or editUrl) and if absent fall back to copying the article text (call the
existing copyArticleText or copyToClipboard helper) and provide user feedback
instead of just closing, and also update the AiActionsDropdown button rendering
to disable the "Copy page" button when neither rawUrl nor article text is
available so the action cannot be triggered; reference the copyPage function,
rawUrl/editUrl variables, and the copyArticleText/copyToClipboard helper to
locate where to add the fallback and disable logic.
skills/cow-swap-order-creator.md (1)

531-531: signHash is deprecated in newer eth_account versions.

The acct.signHash(msg_hash) method is deprecated in eth_account >= 0.6.0. Consider noting this in the tooling section or using acct.unsafe_sign_hash() for the newer API (which makes the security implications explicit).

The tooling notes at lines 603-605 partially address version differences but could be more explicit about signHash deprecation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/cow-swap-order-creator.md` at line 531, The current use of
acct.signHash(msg_hash) is deprecated in eth_account >= 0.6.0; update the
implementation to call acct.unsafe_sign_hash(msg_hash) when targeting newer
eth_account releases (and ensure callers are aware of the security
implications), or add a clear tooling note explaining the version-specific API
change and advising use of acct.unsafe_sign_hash versus acct.signHash for older
versions; update the documentation/tooling section that references version
differences (the note around the existing tooling lines) to explicitly mention
the deprecation of signHash and recommend unsafe_sign_hash when appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/AiActionsDropdown/index.tsx`:
- Around line 76-95: In copyPage, the fetch response is read without checking
HTTP status so error pages may be copied; after awaiting fetch(rawUrl) check
res.ok and if false throw or fall through to the existing catch/fallback logic
(or explicitly use the fallback path) instead of calling res.text() for non-OK
responses; update references to res and rawUrl within copyPage to ensure only
successful responses are copied to clipboard and retain the existing article
fallback behavior.
- Around line 64-74: Update the openInChatGPT function to remove the
undocumented hints=search parameter and use a supported/fallback query pattern
(e.g., use only ?q=... like `https://chatgpt.com/?q=${q}` or
`https://chat.openai.com/?q=${q}`), and add a simple fallback strategy in
openInChatGPT that tries the primary URL and, if it fails to load or is
unreliable, opens the alternative URL; keep openInClaude unchanged. Locate the
openInChatGPT function and replace the URL construction accordingly and add a
lightweight fallback attempt/alternative open to ensure resiliency.

---

Nitpick comments:
In `@skills/cow-swap-order-creator.md`:
- Line 531: The current use of acct.signHash(msg_hash) is deprecated in
eth_account >= 0.6.0; update the implementation to call
acct.unsafe_sign_hash(msg_hash) when targeting newer eth_account releases (and
ensure callers are aware of the security implications), or add a clear tooling
note explaining the version-specific API change and advising use of
acct.unsafe_sign_hash versus acct.signHash for older versions; update the
documentation/tooling section that references version differences (the note
around the existing tooling lines) to explicitly mention the deprecation of
signHash and recommend unsafe_sign_hash when appropriate.

In `@src/components/AiActionsDropdown/index.tsx`:
- Around line 76-77: The copyPage handler currently assumes rawUrl/editUrl
exists and silently closes the dropdown when missing; update the copyPage
function to first check rawUrl (and/or editUrl) and if absent fall back to
copying the article text (call the existing copyArticleText or copyToClipboard
helper) and provide user feedback instead of just closing, and also update the
AiActionsDropdown button rendering to disable the "Copy page" button when
neither rawUrl nor article text is available so the action cannot be triggered;
reference the copyPage function, rawUrl/editUrl variables, and the
copyArticleText/copyToClipboard helper to locate where to add the fallback and
disable logic.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00b4a6d and dd8d29a.

📒 Files selected for processing (4)
  • skills/cow-swap-order-creator.md
  • src/components/AiActionsDropdown/index.tsx
  • src/components/AiActionsDropdown/styles.module.css
  • src/theme/DocItem/Layout/index.tsx

Copy link
Contributor

@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

🧹 Nitpick comments (4)
src/components/AiActionsDropdown/styles.module.css (1)

106-108: Hardcoded green color for copied state.

The #16a34a (green) for the copied state could use a CSS variable for consistency with the design system, though hardcoding success colors is common practice.

 .copied .itemLabel {
-  color: `#16a34a`;
+  color: var(--ifm-color-success, `#16a34a`);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/AiActionsDropdown/styles.module.css` around lines 106 - 108,
Replace the hardcoded green in the .copied .itemLabel rule with the
design-system CSS variable (e.g., use var(--color-success) or the project's
standard success token such as var(--success-500)); update the .copied
.itemLabel declaration in src/components/AiActionsDropdown/styles.module.css to
reference that variable so the copied state color follows the global theme
instead of `#16a34a`.
src/components/AiActionsDropdown/index.tsx (2)

55-55: Consider memoizing pageUrl to avoid recalculation on every render.

While this is a minor concern, window.location.href is read on every render. Using useMemo would be cleaner, though the performance impact is negligible.

-  const pageUrl = typeof window !== 'undefined' ? window.location.href : ''
+  const pageUrl = React.useMemo(
+    () => (typeof window !== 'undefined' ? window.location.href : ''),
+    []
+  )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/AiActionsDropdown/index.tsx` at line 55, Memoize the computed
pageUrl to avoid reading window.location.href each render: inside the
AiActionsDropdown component replace the direct const pageUrl = typeof window !==
'undefined' ? window.location.href : '' with a useMemo that returns the same
value (guarding typeof window) and import/use React's useMemo; keep the fallback
'' behavior so server-side renders remain safe and ensure the memo has an empty
dependency array so it only computes once.

76-95: No user feedback when rawUrl is unavailable and copy is silently skipped.

If rawUrl is falsy (no editUrl provided), clicking "Copy page" closes the dropdown without any feedback. Consider either hiding the button when rawUrl is unavailable, or providing fallback behavior.

🔧 Suggested fix - fallback to article text when no rawUrl
   const copyPage = async () => {
-    if (rawUrl) {
-      try {
-        const res = await fetch(rawUrl)
-        const md = await res.text()
-        await navigator.clipboard.writeText(md)
-        setCopied(true)
-        setTimeout(() => setCopied(false), 2000)
-      } catch {
-        // Fallback: copy article text if fetch fails
-        const article = document.querySelector('article')
-        if (article) {
-          await navigator.clipboard.writeText(article.innerText)
-          setCopied(true)
-          setTimeout(() => setCopied(false), 2000)
-        }
+    try {
+      if (rawUrl) {
+        const res = await fetch(rawUrl)
+        if (!res.ok) throw new Error(`HTTP ${res.status}`)
+        const md = await res.text()
+        await navigator.clipboard.writeText(md)
+      } else {
+        throw new Error('No raw URL')
       }
+      setCopied(true)
+      setTimeout(() => setCopied(false), 2000)
+    } catch {
+      // Fallback: copy article text if fetch fails or no rawUrl
+      const article = document.querySelector('article')
+      if (article) {
+        await navigator.clipboard.writeText(article.innerText)
+        setCopied(true)
+        setTimeout(() => setCopied(false), 2000)
+      }
     }
     setOpen(false)
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/AiActionsDropdown/index.tsx` around lines 76 - 95, The
copyPage handler currently does nothing when rawUrl is falsy which closes the
dropdown with no feedback; update copyPage (or the rendering of the "Copy page"
button) to handle that case by falling back to copying the article text when
rawUrl is unavailable: inside copyPage, if rawUrl is falsy query
document.querySelector('article'), copy its innerText via
navigator.clipboard.writeText, call setCopied(true) and reset with setTimeout as
done for the fetch path, and still call setOpen(false) at the end; alternatively
(if you prefer hiding/disable), conditionally hide/disable the button in the
component render based on rawUrl and provide an aria-label/tooltip to explain
why it’s disabled (use the same setCopied/setOpen behavior for consistent UX).
src/theme/DocItem/Layout/index.tsx (1)

11-11: Consider extracting inline style to CSS module for consistency.

The inline style works but could be co-located with the component's styles for maintainability. This is a minor style consistency suggestion.

// In styles.module.css:
// .dropdownWrapper { display: flex; justify-content: flex-end; margin-bottom: -8px; }

// Then:
// <div className={styles.dropdownWrapper}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/theme/DocItem/Layout/index.tsx` at line 11, Extract the inline style on
the div in the Layout component (the element with style={{ display: 'flex',
justifyContent: 'flex-end', marginBottom: -8 }}) into a CSS module: add a class
like .dropdownWrapper { display: flex; justify-content: flex-end; margin-bottom:
-8px; } in a co-located styles.module.css, import it (e.g. import styles from
'./styles.module.css') into src/theme/DocItem/Layout/index.tsx and replace the
inline style with className={styles.dropdownWrapper}; ensure the unit px is
included for margin-bottom and update any existing imports to avoid naming
conflicts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/AiActionsDropdown/index.tsx`:
- Line 106: The dropdown trigger button in AiActionsDropdown currently toggles
open via setOpen(!open) but lacks accessibility attributes; update the button
(the element using className={styles.trigger} and the open/state setter setOpen)
to include aria-expanded={open} (ensure it's a boolean) and aria-haspopup="menu"
(or appropriate popup type) so assistive tech knows the expanded state and role
of the control.

---

Nitpick comments:
In `@src/components/AiActionsDropdown/index.tsx`:
- Line 55: Memoize the computed pageUrl to avoid reading window.location.href
each render: inside the AiActionsDropdown component replace the direct const
pageUrl = typeof window !== 'undefined' ? window.location.href : '' with a
useMemo that returns the same value (guarding typeof window) and import/use
React's useMemo; keep the fallback '' behavior so server-side renders remain
safe and ensure the memo has an empty dependency array so it only computes once.
- Around line 76-95: The copyPage handler currently does nothing when rawUrl is
falsy which closes the dropdown with no feedback; update copyPage (or the
rendering of the "Copy page" button) to handle that case by falling back to
copying the article text when rawUrl is unavailable: inside copyPage, if rawUrl
is falsy query document.querySelector('article'), copy its innerText via
navigator.clipboard.writeText, call setCopied(true) and reset with setTimeout as
done for the fetch path, and still call setOpen(false) at the end; alternatively
(if you prefer hiding/disable), conditionally hide/disable the button in the
component render based on rawUrl and provide an aria-label/tooltip to explain
why it’s disabled (use the same setCopied/setOpen behavior for consistent UX).

In `@src/components/AiActionsDropdown/styles.module.css`:
- Around line 106-108: Replace the hardcoded green in the .copied .itemLabel
rule with the design-system CSS variable (e.g., use var(--color-success) or the
project's standard success token such as var(--success-500)); update the .copied
.itemLabel declaration in src/components/AiActionsDropdown/styles.module.css to
reference that variable so the copied state color follows the global theme
instead of `#16a34a`.

In `@src/theme/DocItem/Layout/index.tsx`:
- Line 11: Extract the inline style on the div in the Layout component (the
element with style={{ display: 'flex', justifyContent: 'flex-end', marginBottom:
-8 }}) into a CSS module: add a class like .dropdownWrapper { display: flex;
justify-content: flex-end; margin-bottom: -8px; } in a co-located
styles.module.css, import it (e.g. import styles from './styles.module.css')
into src/theme/DocItem/Layout/index.tsx and replace the inline style with
className={styles.dropdownWrapper}; ensure the unit px is included for
margin-bottom and update any existing imports to avoid naming conflicts.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd8d29a and 102c4bc.

📒 Files selected for processing (3)
  • src/components/AiActionsDropdown/index.tsx
  • src/components/AiActionsDropdown/styles.module.css
  • src/theme/DocItem/Layout/index.tsx

- Check res.ok before copying fetched markdown to prevent copying
  error page HTML on 404s
- Remove undocumented hints=search param from ChatGPT URL
@data-cowwboy
Copy link
Contributor Author

image

@fairlighteth
Copy link
Contributor

Thanks for this. Couple of feedback points:

  1. See if you can get the button in the content area. E.g. on the right end of the title section
Screenshot 2026-02-27 at 07 42 33
  1. In light mode the grey description text is too light and doesn't have enough contrast. Would work on making it darker tone (matching with whatever is already on the Docs site)
Screenshot 2026-02-27 at 07 43 13

@data-cowwboy
Copy link
Contributor Author

data-cowwboy commented Feb 27, 2026

@fairlighteth done.

image

Copy link
Contributor

@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: 2

🧹 Nitpick comments (1)
src/components/AiActionsDropdown/styles.module.css (1)

100-103: Increase helper text contrast for light mode.

The description text on Line 100-103 is still relatively faint. Bumping one emphasis step improves readability and better matches docs body contrast.

💡 Proposed fix
 .itemDesc {
   font-size: 0.75rem;
-  color: var(--ifm-color-emphasis-700);
+  color: var(--ifm-color-emphasis-800);
   line-height: 1.3;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/AiActionsDropdown/styles.module.css` around lines 100 - 103,
Update the .itemDesc rule to use a higher-contrast emphasis token for light mode
by changing its color from var(--ifm-color-emphasis-700) to
var(--ifm-color-emphasis-600); if your project uses a light-mode scope (e.g.,
.theme-light or :root when not dark), apply the var(--ifm-color-emphasis-600)
specifically under that scope so only light mode increases helper text contrast
while leaving dark mode unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/AiActionsDropdown/styles.module.css`:
- Around line 20-23: Remove the CSS Modules :global() wrapper from the
dark-theme selector so stylelint stops flagging the pseudo-class; change the
selector from ":global(html[data-theme='dark']) .trigger" to
"html[data-theme='dark'] .trigger" in styles.module.css so the .trigger rule
remains scoped by CSS Modules but avoids the unknown pseudo-class error.

In `@src/theme/DocItem/Content/index.tsx`:
- Around line 31-34: The inline style using marginBottom: -16 on the wrapper div
(rendered when !syntheticTitle) is a fragile layout hack; remove the negative
margin and replace it with a predictable spacing rule—either add a className to
the div and define a margin or padding in CSS/SCSS, or use a container spacing
layout (e.g., gap, padding, or a dedicated utility class) so AiActionsDropdown
(with prop metadata.editUrl) aligns without overlapping surrounding content;
update the JSX around syntheticTitle and AiActionsDropdown to use that
class/utility and adjust the surrounding component spacing accordingly.

---

Nitpick comments:
In `@src/components/AiActionsDropdown/styles.module.css`:
- Around line 100-103: Update the .itemDesc rule to use a higher-contrast
emphasis token for light mode by changing its color from
var(--ifm-color-emphasis-700) to var(--ifm-color-emphasis-600); if your project
uses a light-mode scope (e.g., .theme-light or :root when not dark), apply the
var(--ifm-color-emphasis-600) specifically under that scope so only light mode
increases helper text contrast while leaving dark mode unchanged.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 102c4bc and 736b474.

📒 Files selected for processing (3)
  • src/components/AiActionsDropdown/index.tsx
  • src/components/AiActionsDropdown/styles.module.css
  • src/theme/DocItem/Content/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/AiActionsDropdown/index.tsx

Comment on lines +20 to +23
:global(html[data-theme='dark']) .trigger {
background: #CAE9FF;
color: #052B65;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find stylelint configuration files
echo "=== Searching for stylelint config files ==="
fd -HI "stylelint.config.*" 
fd -HI ".stylelintrc*"
echo ""

# Search for relevant rules and patterns in the codebase
echo "=== Searching for selector-pseudo-class-no-unknown and CSS Modules references ==="
rg -n "selector-pseudo-class-no-unknown|ignorePseudoClasses|postcss-css-modules|stylelint-config-css-modules" -S
echo ""

echo "=== Searching for :global usage in CSS ==="
rg ":global\(" -S --type css

Repository: cowprotocol/docs

Length of output: 344


🏁 Script executed:

#!/bin/bash
# Read the stylelint config
echo "=== Content of .stylelintrc.json ==="
cat -n .stylelintrc.json
echo ""

# Check package.json for stylelint plugins and CSS Modules support
echo "=== Searching package.json for stylelint-related dependencies ==="
rg "stylelint|postcss|css-modules" package.json -A 2 -B 2

Repository: cowprotocol/docs

Length of output: 1379


🏁 Script executed:

#!/bin/bash
# Verify the file is indeed a CSS Module
ls -la src/components/AiActionsDropdown/styles.module.css
echo ""

# Search for CI configuration files that might run stylelint
echo "=== Searching for CI/lint config files ==="
fd -HI "\.github|\.gitlab-ci|\.circleci|\.travis|lint" --type f | head -20
echo ""

# Check if there's any package.json and what scripts it has
echo "=== Checking for lint scripts in package.json ==="
rg "\"lint\"|\"stylelint\"" package.json -A 1 -B 1

Repository: cowprotocol/docs

Length of output: 272


🏁 Script executed:

#!/bin/bash
cat -n src/components/AiActionsDropdown/styles.module.css

Repository: cowprotocol/docs

Length of output: 2575


🏁 Script executed:

#!/bin/bash
# Check for GitHub Actions workflows
find .github -type f -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -10
# If .github doesn't exist, search more broadly
if [ ! -d .github ]; then
  echo "No .github directory found"
  fd -HI "\.yml|\.yaml" --type f | grep -i "workflow\|ci\|lint\|action" | head -10
fi

Repository: cowprotocol/docs

Length of output: 207


🏁 Script executed:

#!/bin/bash
# Search GitHub workflows for stylelint or lint commands
echo "=== Searching workflow files for stylelint/lint ==="
rg "stylelint|lint|build" .github/workflows/ -i
echo ""

# Also check if there's a package.json with build/lint scripts
echo "=== Checking package.json for all scripts ==="
rg "\"scripts\"" -A 20 package.json

Repository: cowprotocol/docs

Length of output: 981


Remove the :global() wrapper to resolve the stylelint selector pseudo-class issue.

The selector uses :global(html[data-theme='dark']) which triggers selector-pseudo-class-no-unknown because the current stylelint config extends stylelint-config-standard-scss without CSS Modules support. Since html is a global element and doesn't require wrapping, the selector can be simplified to html[data-theme='dark'] with no functional change. The .trigger class will remain properly scoped by CSS Modules.

Suggested fix
-:global(html[data-theme='dark']) .trigger {
+html[data-theme='dark'] .trigger {
   background: `#CAE9FF`;
   color: `#052B65`;
 }
📝 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
:global(html[data-theme='dark']) .trigger {
background: #CAE9FF;
color: #052B65;
}
html[data-theme='dark'] .trigger {
background: `#CAE9FF`;
color: `#052B65`;
}
🧰 Tools
🪛 Stylelint (17.3.0)

[error] 20-20: Unexpected unknown pseudo-class selector ":global" (selector-pseudo-class-no-unknown)

(selector-pseudo-class-no-unknown)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/AiActionsDropdown/styles.module.css` around lines 20 - 23,
Remove the CSS Modules :global() wrapper from the dark-theme selector so
stylelint stops flagging the pseudo-class; change the selector from
":global(html[data-theme='dark']) .trigger" to "html[data-theme='dark']
.trigger" in styles.module.css so the .trigger rule remains scoped by CSS
Modules but avoids the unknown pseudo-class error.

Comment on lines +31 to +34
{!syntheticTitle && (
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: -16 }}>
<AiActionsDropdown editUrl={metadata.editUrl} />
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid negative margin layout hack on Line 32.

marginBottom: -16 can cause content overlap/spacing drift across pages. Use normal spacing (or a class-based layout rule) for predictable rendering.

💡 Proposed fix
-      {!syntheticTitle && (
-        <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: -16 }}>
+      {!syntheticTitle && (
+        <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 8 }}>
           <AiActionsDropdown editUrl={metadata.editUrl} />
         </div>
       )}
📝 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
{!syntheticTitle && (
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: -16 }}>
<AiActionsDropdown editUrl={metadata.editUrl} />
</div>
{!syntheticTitle && (
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 8 }}>
<AiActionsDropdown editUrl={metadata.editUrl} />
</div>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/theme/DocItem/Content/index.tsx` around lines 31 - 34, The inline style
using marginBottom: -16 on the wrapper div (rendered when !syntheticTitle) is a
fragile layout hack; remove the negative margin and replace it with a
predictable spacing rule—either add a className to the div and define a margin
or padding in CSS/SCSS, or use a container spacing layout (e.g., gap, padding,
or a dedicated utility class) so AiActionsDropdown (with prop metadata.editUrl)
aligns without overlapping surrounding content; update the JSX around
syntheticTitle and AiActionsDropdown to use that class/utility and adjust the
surrounding component spacing accordingly.

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