8000 feat(bridge): add collapsible banner for proxy account information by fairlighteth · Pull Request #5895 · cowprotocol/cowswap · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(bridge): add collapsibl 8000 e banner for proxy account information #5895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 30, 2025

Conversation

fairlighteth
Copy link
Contributor
@fairlighteth fairlighteth commented Jun 26, 2025

Summary

Fixes UI clutter in bridge flow by adding collapsible banners and improving proxy account information display.

Collapsed (default)

Screenshot 2025-06-26 at 15 04 18

Expanded

Screenshot 2025-06-26 at 15 04 26

To Test

  1. Navigate to Bridge tab and initiate a bridge transaction
  • Verify proxy account banner shows collapsed by default with concise message
  • Click arrow icon to expand and see full explanation
  • Confirm only arrow icon is clickable, not entire banner
  • Check font size is smaller (13px) for better visual hierarchy
  1. Complete a bridge transaction
  • Verify proxy recipient address displays correctly in quote details
  • Check network logo appears next to recipient address
  • Confirm wording is clearer ("Your account proxy" vs technical terms)

Background

  • Split monolithic InlineBanner component (337 lines) into focused modules following single responsibility principle.
  • Added CollapsibleInlineBanner variant to reduce visual noise while maintaining access to important proxy account information.

Summary by CodeRabbit

  • New Features

    • Introduced a collapsible informational banner explaining proxy account usage, now visible in the bridge swap confirmation flow.
    • Added a new banner component for collapsible and dismissible inline messages.
  • Improvements

    • Enhanced clarity and grammar in FAQ and token banner texts for a better user experience.
    • Simplified proxy recipient display by removing tooltip and modal interactions.
  • Removals

    • Removed an inline informational banner from the swap confirmation modal.
    • Deleted the previous inline banner component and related exports.
  • Style

    • Updated UI components to support improved and more flexible banner styling.

Copy link
vercel bot commented Jun 26, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
cowfi ✅ Ready (Inspect) Visit Preview Jun 30, 2025 7:39am
explorer-dev ✅ Ready (Inspect) Visit Preview Jun 30, 2025 7:39am
swap-dev ✅ Ready (Inspect) Visit Preview Jun 30, 2025 7:39am
3 Skipped Deployments
Name Status Preview Updated (UTC)
cosmos ⬜️ Ignored (Inspect) Visit Preview Jun 30, 2025 7:39am
sdk-tools ⬜️ Ignored (Inspect) Visit Preview Jun 30, 2025 7:39am
widget-configurator ⬜️ Ignored (Inspect) Visit Preview Jun 30, 2025 7:39am

Copy link
Contributor
coderabbitai bot commented Jun 26, 2025

Walkthrough

This update refactors the banner components in the UI library, replacing the old InlineBanner with a new implementation and introducing a collapsible variant. It also updates user-facing text for clarity and grammar in several frontend components, removes an inline banner from the swap confirmation modal, and adds a new ProxyAccountBanner for bridge-related UI.

Changes

File(s) Change Summary
apps/cowswap-frontend/src/modules/cowShed/pure/CoWShedFAQ.tsx
apps/cowswap-frontend/src/modules/cowShed/pure/TokensInProxyBanner/index.tsx
Updated FAQ and banner text for clarity and grammar; no logic changes.
apps/cowswap-frontend/src/modules/swap/containers/SwapConfirmModal/index.tsx Removed inline banner and related imports from swap confirmation modal.
apps/cowswap-frontend/src/modules/bridge/pure/ProxyAccountBanner/index.tsx Added new ProxyAccountBanner component showing proxy account info with collapsible details.
apps/cowswap-frontend/src/modules/bridge/pure/contents/QuoteSwapContent/index.tsx Integrated ProxyAccountBanner into the quote swap content UI.
apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx Removed tooltip and modal logic; simplified proxy address display.
libs/ui/src/containers/InlineBanner/index.tsx Deleted old InlineBanner component and its exports.
libs/ui/src/index.ts Updated exports: moved InlineBanner to pure, added CollapsibleInlineBanner.
libs/ui/src/pure/CollapsibleInlineBanner/index.tsx
libs/ui/src/pure/CollapsibleInlineBanner/styled.ts
Added new collapsible inline banner component and its styled components.
libs/ui/src/pure/InlineBanner/InlineBanner/index.tsx
libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts
Added new InlineBanner implementation and its styled components.
libs/ui/src/pure/InlineBanner/shared/BannerIcon.tsx
libs/ui/src/pure/InlineBanner/shared/types.ts
Added shared icon rendering logic and type definitions for banner components.
libs/ui/src/pure/InlineBanner/index.ts New module re-exporting all banner-related exports for simplified imports.
libs/ui/src/pure/DismissableInlineBanner/index.tsx Updated imports and explicit return type for dismissable banner; logic unchanged.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant QuoteSwapContent
  participant ProxyAccountBanner
  participant CollapsibleInlineBanner

  User->>QuoteSwapContent: Opens quote swap UI
  QuoteSwapContent->>ProxyAccountBanner: Renders with recipient, chainId
  ProxyAccountBanner->>CollapsibleInlineBanner: Renders banner (collapsed/expanded)
  User->>CollapsibleInlineBanner: Toggles banner for more/less info
Loading

Possibly related PRs

Suggested reviewers

  • elena-zh
  • shoom3301

Poem

🐇✨
A banner anew, collapsible too,
With icons and styles, all fresh for you!
Proxy accounts now clearly explained,
Old banners retired, new logic maintained.
With every hop, the UI grows bright—
Rabbits rejoice in changes light!

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.

yarn install v1.22.22
[1/4] Resolving packages...
(node:18126) [DEP0169] DeprecationWarning: url.parse() behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for url.parse() vulnerabilities.
(Use node --trace-deprecation ... to show where the warning was created)
[2/4] Fetching packages...
error nx@21.0.3: The engine "node" is incompatible with this module. Expected version "^20.19.0 || ^22.12.0". Got "24.3.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e10da41 and 1e2baa1.

📒 Files selected for processing (2)
  • apps/cowswap-frontend/src/modules/bridge/pure/ProxyAccountBanner/index.tsx (1 hunks)
  • apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cowswap-frontend/src/modules/bridge/pure/ProxyAccountBanner/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Setup
  • GitHub Check: Cypress
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

if (!isCollapsible) return

const newExpanded = !isExpanded
setIsExpanded(newExpanded)
Copy link
Collaborator

Choose a reason for hiding this comment

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

P.s. it can be shorter:

setIsExpanded(state => !state)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed

@fairlighteth fairlighteth changed the title Fix/cowshed displaying style feat(bridge): add collapsible banner for proxy account information Jun 26, 2025

import { CollapsibleInlineBannerProps } from '../shared/types'

export function CollapsibleInlineBanner({
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. The component doesn't have external deps, so it's pure
  2. It looks generic enough and can be placed into ui lib

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed, move it to a separate pure component (separate from InlineBanner folder too)

import { InlineBannerProps } from '../shared/types'
import { renderIcon } from '../shared/utils'

export function InlineBanner({
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's also pure, so it should be in pure directory instead of containers

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed

import { Icon, IconType } from '../../../pure/Icon'
import { StatusColorEnums, StatusColorVariant } from '../../../theme/statusColors'

export function renderIcon(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Render functions are not preferrable due to performance reasons, it's better to make it a component

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: 0

🧹 Nitpick comments (2)
libs/ui/src/containers/InlineBanner/InlineBanner/index.tsx (1)

42-45: Consider simplifying the content wrapping logic.

The conditional wrapping appears redundant since the content is already inside a span wrapper:

<span>
  {renderIcon(...)}
  {noWrapContent ? children : <span>{children}</span>}
</span>

Consider simplifying to:

<span>
  {renderIcon(...)}
  {children}
</span>

Unless there's a specific styling reason for the double span wrapper that isn't apparent from this context.

libs/ui/src/containers/InlineBanner/shared/utils.ts (1)

8-41: Consider safer type handling for icon property.

The function logic is sound and handles all icon rendering scenarios appropriately. However, the type assertion on line 28 could be unsafe if colorEnums.icon doesn't match the IconType enum.

Consider adding runtime validation or using a type guard:

  if (colorEnums.icon) {
+   // Type guard to ensure icon is valid IconType
+   const isValidIconType = Object.values(IconType).includes(colorEnums.icon as IconType)
+   if (!isValidIconType) {
+     console.warn(`Invalid icon type: ${colorEnums.icon}`)
+     return null
+   }
+   
    return React.createElement(Icon, {
      image: colorEnums.icon as IconType,
      size: iconSize,
      color: colorEnums.color,
      description: bannerType,
      padding: iconPadding,
    })
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0692597 and a35e9ba.

📒 Files selected for processing (12)
  • apps/cowswap-frontend/src/modules/bridge/pure/QuoteDetails/index.tsx (2 hunks)
  • apps/cowswap-frontend/src/modules/cowShed/pure/CoWShedFAQ.tsx (2 hunks)
  • apps/cowswap-frontend/src/modules/cowShed/pure/TokensInProxyBanner/index.tsx (2 hunks)
  • apps/cowswap-frontend/src/modules/swap/containers/SwapConfirmModal/index.tsx (0 hunks)
  • libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/index.tsx (1 hunks)
  • libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/styled.ts (1 hunks)
  • libs/ui/src/containers/InlineBanner/InlineBanner/index.tsx (1 hunks)
  • libs/ui/src/containers/InlineBanner/InlineBanner/styled.ts (1 hunks)
  • libs/ui/src/containers/InlineBanner/index.ts (1 hunks)
  • libs/ui/src/containers/InlineBanner/index.tsx (0 hunks)
  • libs/ui/src/containers/InlineBanner/shared/types.ts (1 hunks)
  • libs/ui/src/containers/InlineBanner/shared/utils.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • apps/cowswap-frontend/src/modules/swap/containers/SwapConfirmModal/index.tsx
  • libs/ui/src/containers/InlineBanner/index.tsx
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5443
File: apps/cowswap-frontend/src/modules/swap/containers/ConfirmSwapModalSetup/index.tsx:71-71
Timestamp: 2025-02-20T15:59:33.749Z
Learning: The swap module in apps/cowswap-frontend/src/modules/swap/ is marked for deletion in PR #5444 as part of the swap widget unification effort.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5881
File: apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx:68-72
Timestamp: 2025-06-25T07:28:32.570Z
Learning: In the ProxyRecipient component (apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx), throwing an error when recipient address doesn't match proxy address is intentional design choice to prevent proceeding with incorrect data and ensure data integrity.
Learnt from: alfetopito
PR: cowprotocol/cowswap#5762
File: apps/cowswap-frontend/src/legacy/state/orders/utils.ts:499-503
Timestamp: 2025-05-27T12:20:54.659Z
Learning: In the CowSwap frontend, when displaying volume fees in the UI (like in ReceiptModal), zero fees (0 bps) should be treated as "free" and hidden from display. Only non-zero fees should show the "Total fee" line. This provides a cleaner UX by not cluttering the interface with "0.00%" fee displays.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5859
File: apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts:76-82
Timestamp: 2025-06-23T07:03:50.760Z
Learning: In the useTradeQuotePolling hook, there are two useLayoutEffect hooks that work together: one resets the counter to 0 when the confirmation modal closes, and another automatically triggers pollQuote(false, true) whenever the counter reaches 0. This creates an intentional chain reaction for immediate quote updates.
apps/cowswap-frontend/src/modules/cowShed/pure/TokensInProxyBanner/index.tsx (2)
Learnt from: shoom3301
PR: cowprotocol/cowswap#5881
File: apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx:68-72
Timestamp: 2025-06-25T07:28:32.570Z
Learning: In the ProxyRecipient component (apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx), throwing an error when recipient address doesn't match proxy address is intentional design choice to prevent proceeding with incorrect data and ensure data integrity.
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
libs/ui/src/containers/InlineBanner/InlineBanner/index.tsx (1)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
apps/cowswap-frontend/src/modules/bridge/pure/QuoteDetails/index.tsx (7)
Learnt from: shoom3301
PR: cowprotocol/cowswap#5881
File: apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx:68-72
Timestamp: 2025-06-25T07:28:32.570Z
Learning: In the ProxyRecipient component (apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx), throwing an error when recipient address doesn't match proxy address is intentional design choice to prevent proceeding with incorrect data and ensure data integrity.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5443
File: apps/cowswap-frontend/src/modules/swap/containers/ConfirmSwapModalSetup/index.tsx:71-71
Timestamp: 2025-02-20T15:59:33.749Z
Learning: The swap module in apps/cowswap-frontend/src/modules/swap/ is marked for deletion in PR #5444 as part of the swap widget unification effort.
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5859
File: apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts:76-82
Timestamp: 2025-06-23T07:03:50.760Z
Learning: In the useTradeQuotePolling hook, there are two useLayoutEffect hooks that work together: one resets the counter to 0 when the confirmation modal closes, and another automatically triggers pollQuote(false, true) whenever the counter reaches 0. This creates an intentional chain reaction for immediate quote updates.
Learnt from: alfetopito
PR: cowprotocol/cowswap#5831
File: apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx:7-9
Timestamp: 2025-06-16T16:01:46.729Z
Learning: React Router v7 restructured packages - NavLink and other core routing components should be imported from 'react-router' (not 'react-router-dom'). In v7, 'react-router-dom' mainly re-exports for backward compatibility, while 'react-router' is the new preferred import path for most components.
Learnt from: alfetopito
PR: cowprotocol/cowswap#5830
File: apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx:1-2
Timestamp: 2025-06-16T15:58:00.268Z
Learning: JSX can be imported as a named export from React in modern React versions (React 17+). The import `import { JSX } from 'react'` is valid and does not cause compilation errors.
Learnt from: alfetopito
PR: cowprotocol/cowswap#5831
File: apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx:7-9
Timestamp: 2025-06-16T16:01:46.729Z
Learning: In React Router v6+, NavLink can be imported directly from 'react-router' package, not just 'react-router-dom'. The package structure has evolved and the import from 'react-router' is valid for the latest versions.
apps/cowswap-frontend/src/modules/cowShed/pure/CoWShedFAQ.tsx (2)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5881
File: apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx:68-72
Timestamp: 2025-06-25T07:28:32.570Z
Learning: In the ProxyRecipient component (apps/cowswap-frontend/src/modules/cowShed/containers/ProxyRecipient/index.tsx), throwing an error when recipient addr
67ED
ess doesn't match proxy address is intentional design choice to prevent proceeding with incorrect data and ensure data integrity.
libs/ui/src/containers/InlineBanner/InlineBanner/styled.ts (1)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/index.tsx (2)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
Learnt from: alfetopito
PR: cowprotocol/cowswap#5830
File: apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx:1-2
Timestamp: 2025-06-16T15:58:00.268Z
Learning: JSX can be imported as a named export from React in modern React versions (React 17+). The import `import { JSX } from 'react'` is valid and does not cause compilation errors.
libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/styled.ts (1)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
🧬 Code Graph Analysis (5)
libs/ui/src/containers/InlineBanner/shared/utils.ts (1)
libs/ui/src/theme/statusColors.ts (1)
  • StatusColorEnums (13-20)
apps/cowswap-frontend/src/modules/bridge/pure/QuoteDetails/index.tsx (1)
libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/index.tsx (1)
  • CollapsibleInlineBanner (11-58)
apps/cowswap-frontend/src/modules/cowShed/pure/CoWShedFAQ.tsx (1)
libs/ui/src/containers/ExternalLink/index.tsx (1)
  • ExternalLink (50-89)
libs/ui/src/containers/InlineBanner/InlineBanner/styled.ts (1)
libs/ui/src/theme/statusColors.ts (1)
  • StatusColorEnums (13-20)
libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/index.tsx (2)
libs/ui/src/containers/InlineBanner/shared/types.ts (1)
  • CollapsibleInlineBannerProps (29-35)
libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/styled.ts (4)
  • StyledCollapsibleBanner (60-66)
  • ClickableWrapper (52-58)
  • ToggleIconContainer (6-21)
  • StyledToggleArrow (23-50)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cypress
🔇 Additional comments (19)
libs/ui/src/containers/InlineBanner/shared/types.ts (3)

5-8: Well-designed enum with clear naming convention.

The BannerOrientation enum uses consistent string values that clearly indicate the layout direction.


10-27: Comprehensive interface with good flexibility.

The InlineBannerProps interface provides extensive customization options while keeping all properties optional, allowing for flexible usage patterns.


29-35: Smart design pattern for collapsible content.

The CollapsibleInlineBannerProps interface cleverly omits children from the base interface and instead requires collapsedContent and expandedContent, which is the appropriate pattern for a component that displays different content based on its state.

libs/ui/src/containers/InlineBanner/index.ts (1)

1-3: Standard and well-organized re-export pattern.

This consolidation creates a clean public API for the banner components, making imports easier for consumers.

apps/cowswap-frontend/src/modules/cowShed/pure/TokensInProxyBanner/index.tsx (2)

39-39: Improved grammar with proper article usage.

Adding "the" before "following tokens" makes the sentence grammatically correct.


51-51: Enhanced clarity and sentence structure.

The revised text improves readability by using conditional phrasing ("If something goes wrong") and clearer instructions ("using the Recover funds tab").

apps/cowswap-frontend/src/modules/bridge/pure/QuoteDetails/index.tsx (2)

4-6: Appropriate imports for the new banner functionality.

The imports for CollapsibleInlineBanner and AddressLink are correctly added to support the new informational banner.


60-80: Well-implemented informational banner with good UX.

The CollapsibleInlineBanner implementation provides excellent user experience:

  • Uses appropriate styling (Info variant, horizontal orientation, 13px font size)
  • Collapsed state is concise while expanded state provides helpful detail
  • Consistent use of AddressLink for the recipient address in both states
  • Clear messaging about proxy account functionality
  • Logically positioned between swap and bridge sections
libs/ui/src/containers/InlineBanner/InlineBanner/index.tsx (3)

9-27: Well-structured component with comprehensive props.

The component signature provides extensive customization options with sensible defaults, supporting the flexible design requirements.


47-47: Proper conditional rendering of close functionality.

The close icon is correctly rendered only when an onClose callback is provided, maintaining clean UI when dismissal isn't needed.


52-52: Convenient re-export of shared types.

Re-exporting the shared types from this component file provides easy access for consumers.

apps/cowswap-frontend/src/modules/cowShed/pure/CoWShedFAQ.tsx (1)

17-34: Text improvements enhance clarity and professionalism.

The revised wording makes the FAQ more user-friendly and professional:

  • "also known as" reads better than "aka"
  • "improves" is more formal than "enhances"
  • The contract deployment explanation is clearer and more structured
  • The fund recovery explanation is more precise about potential edge cases
libs/ui/src/containers/InlineBanner/InlineBanner/styled.ts (2)

8-92: Well-structured styling with comprehensive customization options.

The styled components provide excellent flexibility with proper theme integration and responsive design. The complex nested selectors appropriately target specific content elements within the banner structure.


94-109: Clean close icon implementation with proper positioning and interactions.

The close icon styling is well-implemented with smooth transitions, proper positioning, and clear hover states using CSS variables and theme constants.

libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/index.tsx (2)

11-58: Excellent implementation with proper accessibility and state management.

The component demonstrates solid React practices:

  • Clean state management with appropriate default values
  • Proper keyboard accessibility (Enter/Space key support)
  • ARIA attributes for screen readers
  • Guard clauses for conditional behavior
  • Consistent event handling patterns

The conditional rendering logic correctly handles both collapsible and non-collapsible modes.


29-34: Good keyboard accessibility implementation.

The keyboard event handler properly supports both Enter and Space keys with preventDefault() to avoid unintended page scrolling, following accessibility best practices.

libs/ui/src/containers/InlineBanner/CollapsibleInlineBanner/styled.ts (3)

6-21: Well-designed toggle icon container with smooth interactions.

The styling provides excellent user feedback with smooth opacity and background transitions on hover, using consistent theme variables for timing and colors.


23-50: Smooth arrow rotation animation with proper sizing.

The toggle arrow implementation is excellent:

  • Clean rotation logic based on isOpen state
  • Consistent sizing with CSS custom properties
  • Proper color inheritance and hover states
  • Smooth transitions for both transform and fill properties

60-66: Appropriate extension of base InlineBanner with conditional padding.

The collapsible banner correctly extends the base component while adjusting padding based on expansion state, maintaining visual hierarchy between collapsed and expanded states.

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)
libs/ui/src/pure/InlineBanner/shared/utils.ts (1)

8-41: Consider using JSX for better readability.

The function logic is correct and handles all icon rendering scenarios properly. However, the React.createElement calls could be simplified using JSX for better readability:

  if (customIcon) {
    return typeof customIcon === 'string' ? (
-     React.createElement(SVG, { src: customIcon, width: iconSize, height: iconSize })
+     <SVG src={customIcon} width={iconSize} height={iconSize} />
    ) : (
      customIcon
    )
  }

  if (colorEnums.icon) {
-   return React.createElement(Icon, {
-     image: colorEnums.icon as IconType,
-     size: iconSize,
-     color: colorEnums.color,
-     description: bannerType,
-     padding: iconPadding,
-   })
+   return (
+     <Icon
+       image={colorEnums.icon as IconType}
+       size={iconSize}
+       color={colorEnums.color}
+       description={bannerType}
+       padding={iconPadding}
+     />
+   )
  }

  if (colorEnums.iconText) {
-   return React.createElement('i', null, colorEnums.iconText)
+   return <i>{colorEnums.iconText}</i>
  }
libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts (1)

8-35: Consider reducing prop complexity for better maintainability.

The Wrapper component accepts many props (9 optional props), which provides flexibility but may indicate high complexity. While this supports the refactoring goals mentioned in the PR objectives, consider if some props could be grouped or if default styling could be extracted into design tokens.

The implementation correctly uses CSS variables and provides sensible defaults. The conditional padding logic for dismissable banners is well-handled.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a35e9ba and 41c1924.

📒 Files selected for processing (10)
  • libs/ui/src/index.ts (1 hunks)
  • libs/ui/src/pure/CollapsibleInlineBanner/index.tsx (1 hunks)
  • libs/ui/src/pure/CollapsibleInlineBanner/styled.ts (1 hunks)
  • libs/ui/src/pure/DismissableInlineBanner/index.tsx (1 hunks)
  • libs/ui/src/pure/InlineBanner/InlineBanner/index.tsx (1 hunks)
  • libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts (1 hunks)
  • libs/ui/src/pure/InlineBanner/index.ts (1 hunks)
  • libs/ui/src/pure/InlineBanner/shared/BannerIcon.tsx (1 hunks)
  • libs/ui/src/pure/InlineBanner/shared/types.ts (1 hunks)
  • libs/ui/src/pure/InlineBanner/shared/utils.ts (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • libs/ui/src/pure/InlineBanner/index.ts
  • libs/ui/src/index.ts
  • libs/ui/src/pure/CollapsibleInlineBanner/styled.ts
  • libs/ui/src/pure/InlineBanner/shared/types.ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
Learnt from: shoom3301
PR: cowprotocol/cowswap#5859
File: apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts:76-82
Timestamp: 2025-06-23T07:03:50.760Z
Learning: In the useTradeQuotePolling hook, there are two useLayoutEffect hooks that work together: one resets the counter to 0 when the confirmation modal closes, and another automatically triggers pollQuote(false, true) whenever the counter reaches 0. This creates an intentional chain reaction for immediate quote updates.
libs/ui/src/pure/CollapsibleInlineBanner/index.tsx (1)
Learnt from: alfetopito
PR: cowprotocol/cowswap#5830
File: apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx:1-2
Timestamp: 2025-06-16T15:58:00.268Z
Learning: JSX can be imported as a named export from React in modern React versions (React 17+). The import `import { JSX } from 'react'` is valid and does not cause compilation errors.
libs/ui/src/pure/InlineBanner/shared/BannerIcon.tsx (1)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts (1)
Learnt from: fairlighteth
PR: cowprotocol/cowswap#5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
🧬 Code Graph Analysis (5)
libs/ui/src/pure/DismissableInlineBanner/index.tsx (1)
libs/ui/src/pure/InlineBanner/shared/types.ts (1)
  • InlineBannerProps (10-27)
libs/ui/src/pure/CollapsibleInlineBanner/index.tsx (2)
libs/ui/src/pure/InlineBanner/shared/types.ts (1)
  • CollapsibleInlineBannerProps (29-35)
libs/ui/src/pure/CollapsibleInlineBanner/styled.ts (4)
  • StyledCollapsibleBanner (60-66)
  • ClickableWrapper (52-58)
  • ToggleIconContainer (6-21)
  • StyledToggleArrow (23-50)
libs/ui/src/pure/InlineBanner/shared/BannerIcon.tsx (1)
libs/ui/src/theme/statusColors.ts (1)
  • StatusColorEnums (13-20)
libs/ui/src/pure/InlineBanner/shared/utils.ts (1)
libs/ui/src/theme/statusColors.ts (1)
  • StatusColorEnums (13-20)
libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts (1)
libs/ui/src/theme/statusColors.ts (1)
  • StatusColorEnums (13-20)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Cypress
  • GitHub Check: Setup
🔇 Additional comments (7)
libs/ui/src/pure/DismissableInlineBanner/index.tsx (1)

1-1: LGTM! Clean refactoring to support the new pure component structure.

The import updates and explicit return type annotation properly align with the component migration from containers to pure modules.

Also applies to: 4-4, 10-10

libs/ui/src/pure/InlineBanner/InlineBanner/index.tsx (2)

9-57: Excellent implementation of the new InlineBanner component.

The component demonstrates good practices:

  • Clean prop destructuring with sensible defaults
  • Proper separation of concerns with the BannerIcon component
  • Conditional rendering logic is clear and efficient
  • Type safety maintained throughout

59-59: Good practice re-exporting shared types.

This maintains a clean API boundary for consumers of the component.

libs/ui/src/pure/CollapsibleInlineBanner/index.tsx (2)

11-58: Excellent implementation with proper accessibility and React best practices.

The component demonstrates several strengths:

  • Accessibility: Proper ARIA labels, keyboard navigation support (Enter/Space), and semantic button role
  • State management: Clean useState implementation with optional callback support
  • Performance: Early return for non-collapsible case avoids unnecessary rendering
  • UX: Proper event handling with preventDefault for keyboard interactions

The conditional rendering logic is clear and the component API is well-designed.


60-60: Good practice re-exporting shared types.

This maintains a consistent API for consumers who need access to the type definitions.

libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts (2)

1-6: LGTM: Clean imports and proper dependencies.

The imports are well-organized and appropriate for the styled components implementation.


94-109: LGTM: Well-implemented close icon with good UX.

The CloseIcon implementation follows good practices:

  • Uses CSS variables for consistent sizing
  • Appropriate positioning and hover effects
  • Good use of the UI.ANIMATION_DURATION constant for consistent transitions
  • Proper cursor indication for interactivity

Comment on lines +36 to +92
// Icon + Text content wrapper
> span {
display: flex;
justify-content: center;
align-items: center;
flex-flow: ${({ orientation = BannerOrientation.Vertical }) =>
orientation === BannerOrientation.Horizontal ? 'row' : 'column wrap'};
gap: 10px;
width: auto;
}

> span > svg > path {
fill: ${({ colorEnums }) => `var(${colorEnums.iconColor})`};
}

// Text content
> span > span {
width: 100%;
display: flex;
flex-flow: row wrap;
align-items: center;
gap: 10px;
justify-content: ${({ orientation = BannerOrientation.Vertical }) =>
orientation === BannerOrientation.Horizontal ? 'flex-start' : 'center'};

a {
color: inherit;
text-decoration: underline;
}

> strong {
display: flex;
align-items: center;
text-align: center;
gap: 6px;
}

> p {
line-height: 1.4;
margin: auto;
padding: 0;
width: 100%;
text-align: ${({ orientation = BannerOrientation.Vertical }) =>
orientation === BannerOrientation.Horizontal ? 'left' : 'center'};
}

> i {
font-style: normal;
font-size: 32px;
line-height: 1;
}

> ol {
padding-left: 20px;
}
}
`
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify deeply nested selectors for better maintainability.

The nested selectors (e.g., > span > svg > path, > span > span) create tight coupling to the DOM structure and can be fragile during refactoring.

Consider using CSS classes or data attributes for more maintainable styling:

- > span > svg > path {
-   fill: ${({ colorEnums }) => `var(${colorEnums.iconColor})`};
- }
+ [data-banner-icon] path {
+   fill: ${({ colorEnums }) => `var(${colorEnums.iconColor})`};
+ }

- > span > span {
+ [data-banner-content] {
   width: 100%;
   display: flex;
   // ... rest of styles

This approach would require adding corresponding data attributes to the JSX elements but provides more resilient styling.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In libs/ui/src/pure/InlineBanner/InlineBanner/styled.ts between lines 36 and 92,
the current deeply nested selectors like '> span > svg > path' and '> span >
span' tightly couple styles to the DOM structure, making maintenance and
refactoring difficult. To fix this, replace these nested selectors with CSS
classes or data attributes applied directly to the JSX elements, then update the
styled components to target those classes or attributes instead. This will
decouple styling from the DOM hierarchy and improve maintainability.

@fairlighteth
Copy link
Contributor Author
fairlighteth commented Jun 26, 2025

@elena-zh thank you for your review!

  1. Yeah I think so. As long as the recipient on swap is different from user's EOA I think it's right to show the banner.
  2. Fixed!

@elena-zh
Copy link
Contributor

@fairlighteth , for me it looks like there is too much info close one to another (and partially repeated)
image
image
As a compromise, WDYT about showing a collapsed version of the text (oinly collapsed) on the swap widget? ;)

Btw, I see that there are some issues with the build:
image

@fairlighteth
Copy link
Contributor Author

@elena-zh Came up with a different solution now, where I removed the tooltip and conslidated things into the expandable inline banner:
Screenshot 2025-06-28 at 17 20 46

Screenshot 2025-06-28 at 17 20 53
  • Build is also fixed

Copy link
Contributor
@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

@fairlighteth , thank you, looks good!

@shoom3301 shoom3301 merged commit 0825186 into develop Jun 30, 2025
14 of 15 checks passed
@shoom3301 shoom3301 deleted the fix/cowshed-displaying-style branch June 30, 2025 11:19
@github-actions github-actions bot locked and limited conversation to collaborators Jun 30, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
@fairlighteth 3387 @elena-zh @shoom3301
0