Skip to content

Conversation

@kyrers
Copy link

@kyrers kyrers commented Dec 16, 2025

Resolves #127.


PR-Codex overview

This PR focuses on refactoring the codebase to remove styled-components, integrate tailwindcss, and enhance component structure. It improves accessibility and responsiveness while updating various components to streamline the UI.

Detailed summary

  • Removed multiple unused styled-components files.
  • Replaced styled-components with tailwindcss classes in various components.
  • Updated button props from onClick to onPress.
  • Simplified component structures for better readability.
  • Refactored styles in multiple components to use Tailwind CSS utility classes.
  • Removed deprecated theme usage and updated theme context.
  • Consolidated breakpoint handling using a new LG_BREAKPOINT.
  • Enhanced responsiveness and accessibility across components.

The following files were skipped due to too many changes: web/src/pages/NewTransaction/index.tsx, web/src/layout/Header/navbar/Menu/Settings/index.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx, web/src/layout/Header/navbar/Menu/Settings/General.tsx, web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx, web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx, web/src/components/ConnectWallet/AccountDisplay.tsx, web/src/global.css, yarn.lock

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Account display now prefers ENS name and avatar and has improved responsive layout.
    • Persistent light/dark theme toggle that applies via a CSS class and remembers your choice.
  • Chores

    • Migrated UI styling to a consolidated global CSS and utility-first classes for more consistent theming, spacing, and scrollbars.
    • Added Tailwind tooling and a safe class-name merging utility.
    • Upgraded the UI component library.

✏️ Tip: You can customize this high-level summary in your review settings.

@kyrers kyrers self-assigned this Dec 16, 2025
@netlify
Copy link

netlify bot commented Dec 16, 2025

Deploy Preview for kleros-escrow-v2 failed. Why did it fail? →

Name Link
🔨 Latest commit bc774cb
🔍 Latest deploy log https://app.netlify.com/projects/kleros-escrow-v2/deploys/694479c313b94b0008da4a56

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

Walkthrough

Removes styled-components theming and many CSS-in-JS utilities; adds Tailwind toolchain and global.css; replaces styled components with utility-class/cn markup; swaps top-level StyledComponentsProvider for a new ThemeProvider that toggles a .dark class; upgrades @kleros/ui-components-library and adapts Button API (onClickonPress, disabledisDisabled).

Changes

Cohort / File(s) Summary
Deps & Build
\web/package.json`, `web/vite.config.js``
Upgrade @kleros/ui-components-library → ^3.6.0; remove styled-components and @types/styled-components; add tailwindcss, @tailwindcss/vite, clsx, tailwind-merge; register tailwindcss() plugin in Vite config.
Global styles & types
\web/src/global.css`, `web/src/styles/global-style.ts`, `web/global.d.ts``
Add global.css with CSS variables and Tailwind-oriented rules; delete global-style.ts (createGlobalStyle); remove styled-components module augmentation and add top-level export {} in global.d.ts.
Top-level app & provider
\web/src/app.tsx`, `web/src/context/StyledComponentsProvider.tsx` (deleted), `web/src/context/ThemeProvider.tsx``
Replace removed StyledComponentsProvider with new ThemeProvider; import global CSS and overlayscrollbars; ThemeProvider persists `"light"
Theming & styles removed
\web/src/styles/themes.ts`, `web/src/styles/customScrollbar.ts`, `web/src/styles/commonStyles.ts`, `web/src/styles/landscapeStyle.ts``
Remove exported lightTheme/darkTheme and CSS-in-JS utilities (custom scrollbar, hover transitions, landscapeStyle).
Layout & components (presentation)
\web/src/layout/`, `web/src/components/`, `web/src/pages/**``
Replace many styled-components with plain JSX + Tailwind/cn classNames across header, footer, navbar, pages and components; delete multiple styled wrappers and migrate structure to utility classes.
Button API & component props
\web/src/components/LightButton.tsx`, `web/src/components//ConnectWallet/`, `web/src/components/ConnectWallet/AccountDisplay.tsx``
Standardize Button API to onPress and isDisabled; IdenticonOrAvatar now accepts optional address and resolves ENS/avatar; numerous components updated to className-driven styling.
Hooks, breakpoints & provider tweaks
\web/src/hooks/useToggleThemeContext.tsx`, `web/src/styles/breakpoints.ts`, `web/src/context/Web3Provider.tsx``
Rename useToggleThemeuseTheme; add LG_BREAKPOINT = 900; inline primary color constant in Web3Provider replacing dependency on lightTheme.
Utilities
\web/src/utils/index.ts``
Add cn(...inputs) helper combining clsx + tailwind-merge for safe Tailwind class merging.
Deleted/removed exports
assorted (e.g., \web/src/components/ExternalLink.tsx`, `web/src/components/StyledIcons/ClosedCircleIcon.tsx``)
Remove several styled-component exports and replace usages with plain anchors/divs or UI-library components.
API / signature adjustments
assorted (e.g., \web/src/layout/Header/navbar/Menu/Settings/index.tsx`, `web/src/layout/Header/navbar/index.tsx``)
Remove initialTab from Settings signature; add exported interfaces (ISettings, IHelp, IDappList); expose DisconnectWalletButton; adjust props to new Button API and class-based styling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay extra attention to:
    • Residual imports or references to styled-components, createGlobalStyle, or removed theme tokens.
    • Consistency of Button API changes (onClickonPress, disabledisDisabled) across the codebase.
    • Parity between removed GlobalStyle rules and the new global.css (fonts, toast positioning, skeleton colors, scrollbars).
    • Correctness of cn usage and class merging where CSS-in-JS rules were converted.
    • ENS/avatar resolution and the new optional address prop in IdenticonOrAvatar / AccountDisplay.

Possibly related issues

Possibly related PRs

  • escrow-v2#76 — Overlapping edits in app/provider and wallet/account UI (app.tsx, Web3Provider, AccountDisplay).
  • escrow-v2#91 — Overlaps header/navbar changes (MobileHeader and navbar/index); similar migration away from styled-components.
  • escrow-v2#79 — Touches Settings/General; both PRs refactor/remove styled-components in the same area.

Suggested labels

Package: Web, Type: Maintenance :construction:, Type: UX

Suggested reviewers

  • kemuru
  • Harman-singh-waraich
  • alcercu

Poem

🐇 I swapped my stitched-in theme today,
for classed-up hops and Tailwind play.
I toggle light and dark with nimble paws,
clean markup trails and fewer claws. ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changeset focus: migrating to Tailwind CSS and the ui-components-library v3, which are the primary objectives.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #127: migrates to ui-components-library v3, replaces styled-components with Tailwind classes, updates button props (disabled→isDisabled, onClick→onPress), adapts theming context, and improves consistency.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to the Tailwind and ui-components-library v3 migration objectives; no unrelated modifications were detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/tailwind-and-ui-library-migraton

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

@kyrers kyrers force-pushed the chore/tailwind-and-ui-library-migraton branch from f4d2ebb to 9641ce5 Compare December 16, 2025 15:29
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)
web/src/context/ThemeProvider.tsx (1)

10-10: Consider validating the localStorage value.

The code assumes the value from localStorage is a valid Theme type, but malformed or corrupted data could cause issues. Consider adding validation:

-  const [theme, setTheme] = useLocalStorage<Theme>("theme", "dark");
+  const [storedTheme, setTheme] = useLocalStorage<Theme>("theme", "dark");
+  const theme: Theme = storedTheme === "light" || storedTheme === "dark" ? storedTheme : "dark";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0be02aa and 9641ce5.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (15)
  • web/global.d.ts (1 hunks)
  • web/package.json (2 hunks)
  • web/src/app.tsx (3 hunks)
  • web/src/context/StyledComponentsProvider.tsx (0 hunks)
  • web/src/context/ThemeProvider.tsx (1 hunks)
  • web/src/context/Web3Provider.tsx (2 hunks)
  • web/src/global.css (1 hunks)
  • web/src/hooks/useToggleThemeContext.tsx (1 hunks)
  • web/src/layout/index.tsx (0 hunks)
  • web/src/styles/commonStyles.ts (0 hunks)
  • web/src/styles/customScrollbar.ts (0 hunks)
  • web/src/styles/global-style.ts (0 hunks)
  • web/src/styles/landscapeStyle.ts (0 hunks)
  • web/src/styles/themes.ts (0 hunks)
  • web/vite.config.js (2 hunks)
💤 Files with no reviewable changes (7)
  • web/src/styles/global-style.ts
  • web/src/styles/customScrollbar.ts
  • web/src/layout/index.tsx
  • web/src/styles/commonStyles.ts
  • web/src/styles/landscapeStyle.ts
  • web/src/context/StyledComponentsProvider.tsx
  • web/src/styles/themes.ts
🧰 Additional context used
🧬 Code graph analysis (1)
web/src/context/ThemeProvider.tsx (2)
web/src/hooks/useLocalStorage.ts (1)
  • useLocalStorage (3-22)
web/src/hooks/useToggleThemeContext.tsx (1)
  • ToggleThemeProvider (10-16)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
🔇 Additional comments (11)
web/src/context/Web3Provider.tsx (1)

92-92: The hardcoded hex value "#4D00B4" in the AppKit configuration is correct and necessary. This is new code (not a modification), and AppKit's themeVariables requires CSS custom property strings. The color matches the brand primary purple used consistently throughout the codebase (SVGs, styled-components). No refactoring is needed.

Likely an incorrect or invalid review comment.

web/global.d.ts (1)

12-12: LGTM!

The addition of export {} correctly converts this file to a module after removing the styled-components augmentation, which aligns with the migration to Tailwind CSS.

web/src/app.tsx (2)

6-7: LGTM!

The global CSS imports are correctly placed at the top level to ensure styles are applied application-wide.


11-11: LGTM!

The replacement of StyledComponentsProvider with ThemeProvider correctly implements the new theming architecture. The provider wraps the entire application at the appropriate level.

Also applies to: 23-23, 46-46

web/src/context/ThemeProvider.tsx (1)

17-24: LGTM!

The useEffect correctly applies the "dark" class to document.documentElement, which is the standard approach for Tailwind CSS dark mode integration.

web/src/global.css (3)

7-27: LGTM!

The @theme block correctly defines custom CSS variables for colors, spacing, and other design tokens. The use of color-mix() for opacity variants (line 21) is a modern approach that works well with Tailwind v4.


29-32: LGTM!

The dark theme overrides for skeleton colors are correctly scoped to the .dark class, aligning with the ThemeProvider implementation.


105-132: LGTM!

The custom scrollbar styles are well-implemented with proper transitions and theme-aware colors.

web/package.json (2)

72-72: Styled-components successfully removed from codebase.

All styled-components dependencies have been completely removed from package.json and no remaining imports or usage patterns exist in the codebase.


72-72: No action required—@kleros/ui-components-library v3.6.0 is already integrated successfully.

The codebase is actively using v3.6.0 across 30+ components (Button, Field, Card, Steps, Datepicker, FileUploader, Searchbar, AlertMessage, Tooltip, etc.) without reported breaking changes or compatibility issues. The CSS theme import and Tailwind CSS v4 integration are properly configured. The recent refactor to migrate from styled-components to Tailwind CSS indicates the upgrade was completed and tested.

web/vite.config.js (1)

5-5: The Tailwind CSS v4 Vite plugin integration is correct.

The import and plugin registration are properly implemented. The project currently uses @tailwindcss/vite at version ^4.1.17 as specified in web/package.json. Regular dependency updates should be monitored to ensure compatibility with future releases.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 16, 2025
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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/components/ConnectWallet/AccountDisplay.tsx (1)

51-51: Unsafe non-null assertion on potentially undefined address.

When the user is not connected and no propAddress is provided, address will be undefined. The ! assertion is misleading and could cause issues. Consider adding a guard or returning early.

-  return <label>{data ?? (isAddress(address!) ? shortenAddress(address) : address)}</label>;
+  if (!address) return null;
+  return <label>{data ?? (isAddress(address) ? shortenAddress(address) : address)}</label>;
♻️ Duplicate comments (1)
web/src/global.css (1)

1-5: Duplicate: Import order and redundant directive already flagged.

This issue was already identified in a previous review. Please refer to the existing comment about moving @import "tailwindcss" to the top and removing the redundant @tailwind utilities directive.

🧹 Nitpick comments (8)
web/src/layout/Header/navbar/Debug.tsx (2)

6-9: Use <span> instead of <label> for semantic correctness.

The <label> element is semantically intended for form controls. Since this is purely presentational text without an associated input, use <span> instead.

Apply this diff:

-  <label className="text-[10px] leading-2.5 text-klerosUIComponentsStroke font-[Roboto_Mono,monospace]">
+  <span className="text-[10px] leading-2.5 text-klerosUIComponentsStroke font-[Roboto_Mono,monospace]">
     v{RELEASE_VERSION}{" "}
     <a
       className="text-inherit text-[10px] leading-2.5 font-[Roboto_Mono,monospace]"

And update the closing tag at line 19:

-  </label>
+  </span>

8-13: Remove redundant typography classes from the anchor.

The anchor element already inherits font-size, line-height, and font-family from its parent. Only text-inherit is needed to inherit the text color.

Apply this diff:

     <a
-      className="text-inherit text-[10px] leading-2.5 font-[Roboto_Mono,monospace]"
+      className="text-inherit"
       href={GIT_URL}
       target="_blank"
       rel="noreferrer"
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (1)

25-25: Nice refactor: validation as derived value.

Converting emailIsValid from state to a computed value eliminates unnecessary state management since it's directly derived from emailInput.

web/src/components/InfoCard.tsx (1)

1-23: Consider using cn utility for consistency.

This component uses clsx directly (line 1), while other components in the PR use the cn utility from src/utils which combines clsx with twMerge. The cn utility properly merges Tailwind classes and resolves conflicts.

For consistency and to benefit from Tailwind class merging, consider:

-import clsx from "clsx";
 import React from "react";
+import { cn } from "src/utils";
 import InfoCircle from "svgs/icons/info-circle.svg";
 
 interface IInfoCard {
   msg: string;
   className?: string;
 }
 
 const InfoCard: React.FC<IInfoCard> = ({ msg, className }) => {
   return (
     <div
-      className={clsx(
+      className={cn(
         "grid grid-cols-[16px_auto] gap-fluid-6-8-300 items-center justify-start",
         "text-start text-klerosUIComponentsSecondaryText",
         className
       )}
     >
web/src/layout/Header/navbar/Product.tsx (1)

1-41: Consider using cn utility and simplify conditional className.

Similar to InfoCard.tsx, this component uses clsx directly instead of the cn utility. Additionally, line 29 uses a template literal for conditional rendering that could be simplified.

-import clsx from "clsx";
+import { cn } from "src/utils";

 const Product: React.FC<IProduct> = ({ text, url, Icon }) => {
   const [isImgLoaded, setIsImgLoaded] = useState(false);
 
   return (
     <a
       href={url}
       target="_blank"
       rel="noopener noreferrer"
-      className={clsx(
+      className={cn(
         "flex flex-col items-center pt-4 pb-7 px-2 max-w-[100px] w-fluid-100-130 rounded-[3px] gap-2",
         "cursor-pointer bg-klerosUIComponentsLightBackground hover:bg-light-grey dark:hover:bg-klerosUIComponentsLightGrey",
         "hover:transition-[transform_0.15s,background-color_0.3s] hover:scale-[1.02]"
       )}
     >
       {typeof Icon === "string" ? (
         <>
           {!isImgLoaded ? <Skeleton width={48} height={46} circle /> : null}
           <img
-            className={`w-12 h-12 ${isImgLoaded ? "block" : "hidden"}`}
+            className={cn("w-12 h-12", isImgLoaded ? "block" : "hidden")}
             alt={Icon}
             src={Icon}
             onLoad={() => setIsImgLoaded(true)}
           />
web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)

13-62: Consider using cn utility and review arbitrary selector coupling.

Two observations:

  1. Inconsistent utility usage: This component imports clsx (line 6) while other components use the cn utility from src/utils. For consistency and proper Tailwind class merging, consider using cn.

  2. Arbitrary selector coupling: Line 39 uses [&_label]:cursor-pointer which assumes AddressOrName component renders a <label> element. This creates tight coupling between components. Consider verifying this component structure is stable or using a more explicit approach.

-import clsx from "clsx";
+import { cn } from "src/utils";
 
 const General: React.FC = () => {
   // ... rest of component
   return (
     <div className="flex justify-center p-4">
       <EnsureChain>
         <div className="flex flex-col justify-center mt-3">
           {address && (
             <div className="flex flex-col gap-3">
               <div className="flex justify-center mt-3">
                 <IdenticonOrAvatar size="48" />
               </div>
               <div
-                className={clsx(
+                className={cn(
                   "flex justify-center",
                   "[&>label]:text-base [&>label]:font-semibold [&>label]:text-klerosUIComponentsPrimaryText"
                 )}
               >
               {/* ... */}
               <div
-                className={clsx(
+                className={cn(
                   "flex h-[34px] gap-2 justify-center items-center",
web/src/layout/Header/navbar/Menu/index.tsx (1)

47-54: Consider using a stable key instead of index.

While using index as a key works here since the buttons array is static, it's better practice to use a stable identifier like text which is unique for each button.

Apply this diff:

-      {buttons.map(({ text, Icon, onPress }, index) => (
+      {buttons.map(({ text, Icon, onPress }) => (
         <div
-          key={index}
+          key={text}
           className={clsx("flex items-center min-h-8", "[&_.button-text]:block lg:[&_.button-text]:hidden")}
         >
web/src/components/ConnectWallet/AccountDisplay.tsx (1)

26-29: Avoid unnecessary ENS avatar lookups when name is undefined.

When name is undefined, normalize("") is passed to useEnsAvatar, triggering an API call that will never return a valid avatar. Add the query.enabled option to skip the query when there's no name.

  const { data: avatar } = useEnsAvatar({
    name: normalize(name ?? ""),
    chainId: 1,
+   query: {
+     enabled: !!name,
+   },
  });
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9641ce5 and 75568be.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (29)
  • web/package.json (2 hunks)
  • web/src/app.tsx (3 hunks)
  • web/src/components/ConnectWallet/AccountDisplay.tsx (3 hunks)
  • web/src/components/ConnectWallet/index.tsx (2 hunks)
  • web/src/components/EnsureAuth.tsx (1 hunks)
  • web/src/components/InfoCard.tsx (1 hunks)
  • web/src/components/LightButton.tsx (1 hunks)
  • web/src/components/Overlay.tsx (1 hunks)
  • web/src/components/OverlayPortal.tsx (1 hunks)
  • web/src/global.css (1 hunks)
  • web/src/layout/Header/DesktopHeader.tsx (1 hunks)
  • web/src/layout/Header/Logo.tsx (1 hunks)
  • web/src/layout/Header/MobileHeader.tsx (1 hunks)
  • web/src/layout/Header/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/DappList.tsx (2 hunks)
  • web/src/layout/Header/navbar/Debug.tsx (2 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Help.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/General.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (3 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Product.tsx (2 hunks)
  • web/src/layout/Header/navbar/index.tsx (2 hunks)
  • web/src/layout/index.tsx (1 hunks)
  • web/src/utils/index.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • web/package.json
  • web/src/layout/index.tsx
  • web/src/app.tsx
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2024-11-28T14:07:11.735Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/layout/Header/navbar/index.tsx:56-56
Timestamp: 2024-11-28T14:07:11.735Z
Learning: In `web/src/layout/Header/navbar/index.tsx`, it's acceptable not to pass the optional `initialTab` prop when rendering the `Settings` component, as the component handles it with a fallback value.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/General.tsx
  • web/src/layout/Header/navbar/Menu/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
  • web/src/layout/Header/navbar/Explore.tsx
  • web/src/layout/Header/navbar/Menu/Help.tsx
  • web/src/layout/Header/navbar/index.tsx
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2025-04-30T10:21:32.345Z
Learnt from: jaybuidl
Repo: kleros/escrow-v2 PR: 114
File: web/src/components/ScrollTop.tsx:1-33
Timestamp: 2025-04-30T10:21:32.345Z
Learning: In the ScrollTop component, the useEffect with an empty dependency array is intentional as the scrolling logic should only execute once when the component mounts. The component uses a hasScrolled ref to prevent re-executing the scroll logic.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-28T13:58:33.048Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx:44-46
Timestamp: 2024-11-28T13:58:33.048Z
Learning: In `web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx`, when checking `user.emailUpdateableAt`, it's acceptable to use the non-null assertion operator `!` due to type assertion issues preventing standard checks.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-28T14:13:54.217Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/pages/Settings/EmailConfirmation/index.tsx:141-153
Timestamp: 2024-11-28T14:13:54.217Z
Learning: In the `EmailConfirmation` component, adding a cleanup function with an unsubscribed variable inside `useEffect` is unnecessary unless there's a specific need to handle component unmounting or prevent memory leaks.

Applied to files:

  • web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
🧬 Code graph analysis (11)
web/src/components/ConnectWallet/index.tsx (1)
web/src/consts/chains.ts (2)
  • SUPPORTED_CHAINS (9-11)
  • DEFAULT_CHAIN (6-6)
web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (3)
web/src/layout/Header/navbar/index.tsx (1)
  • ISettings (24-27)
web/src/components/EnsureChain.tsx (1)
  • EnsureChain (10-14)
web/src/components/EnsureAuth.tsx (1)
  • EnsureAuth (17-45)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (2)
web/src/components/EnsureChain.tsx (1)
  • EnsureChain (10-14)
web/src/components/ConnectWallet/AccountDisplay.tsx (3)
  • IdenticonOrAvatar (18-36)
  • AddressOrName (42-52)
  • ChainDisplay (54-58)
web/src/components/Overlay.tsx (1)
web/src/utils/index.ts (1)
  • cn (41-43)
web/src/layout/Header/navbar/Menu/index.tsx (2)
web/src/layout/Header/navbar/index.tsx (2)
  • ISettings (24-27)
  • IHelp (29-31)
web/src/hooks/useToggleThemeContext.tsx (1)
  • useTheme (18-20)
web/src/layout/Header/navbar/Explore.tsx (1)
web/src/utils/index.ts (1)
  • cn (41-43)
web/src/components/LightButton.tsx (1)
web/src/utils/index.ts (1)
  • cn (41-43)
web/src/layout/Header/index.tsx (1)
web/src/utils/getGraphqlUrl.ts (1)
  • getGraphqlUrl (4-12)
web/src/layout/Header/navbar/index.tsx (3)
web/src/utils/index.ts (1)
  • cn (41-43)
web/src/components/Overlay.tsx (1)
  • Overlay (9-11)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)
  • DisconnectWalletButton (8-11)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1)
web/src/utils/wrapWithToast.ts (3)
  • infoToast (15-15)
  • successToast (16-16)
  • errorToast (17-17)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (2)
web/src/consts/index.ts (1)
  • EMAIL_REGEX (16-17)
web/src/utils/date.ts (1)
  • timeLeftUntil (32-58)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
🔇 Additional comments (23)
web/src/layout/Header/navbar/Debug.tsx (2)

17-18: LGTM! Enhanced version display with Git metadata.

The conditional rendering for GIT_TAGS and GIT_DIRTY follows the same pattern as the existing GIT_BRANCH check and provides useful debug information.


46-49: LGTM! Clean migration from styled-components.

Replacing the styled Container with a plain div aligns with the Tailwind migration objectives. The wrapper correctly contains the child components without requiring additional styling.

web/src/components/EnsureAuth.tsx (1)

34-43: LGTM!

The refactoring from styled-components to plain HTML with Tailwind classes is clean. The Button prop updates (onClickonPress, disabledisDisabled) correctly align with @kleros/ui-components-library v3.

web/src/layout/Header/Logo.tsx (1)

6-11: LGTM!

The Tailwind v4 syntax is correct: the hover:[&_path]:fill-white/75 uses arbitrary selectors to target SVG paths, and the /75 opacity syntax aligns with v4's updated approach.

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)

1-40: LGTM!

The refactoring simplifies the component by moving validation logic to the parent. The TextField integration is clean, and the nested selector syntax ([&_input]:text-sm [&_label]:self-start) is valid Tailwind v4.

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (2)

17-31: LGTM!

Removing the unused event parameter from resendVerificationEmail simplifies the callback. The refactoring correctly maintains the async flow with toast notifications.


34-58: LGTM!

The conversion from styled-components to Tailwind classes is well-executed. The Button styling with [&_.button-text] selectors correctly targets internal elements using Tailwind v4's arbitrary selector syntax.

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (1)

73-112: LGTM!

The form refactoring from styled-components to plain HTML with Tailwind classes is clean. The custom utility px-fluid-12-32-300 should work with the definitions in global.css, and the button disabled logic is correctly preserved.

web/src/layout/Header/navbar/DappList.tsx (1)

88-111: Fluid spacing utilities are properly configured.

The @theme directive is correctly being used to define theme variables that instruct Tailwind to create new utility classes. The global.css file defines fluid spacing variables following the --spacing-fluid-* namespace pattern (e.g., --spacing-fluid-300-480, --spacing-fluid-8-24), which properly generates corresponding utility classes like w-fluid-300-480 and px-fluid-8-24. Each variable uses the CSS clamp() function for responsive fluid scaling across different viewport sizes, which is the correct approach for Tailwind v4's CSS-native design system.

web/src/utils/index.ts (1)

40-43: LGTM! Standard Tailwind className composition utility.

The cn utility correctly combines clsx for conditional class composition with twMerge for resolving Tailwind class conflicts. This is the recommended pattern for Tailwind CSS projects.

web/src/components/ConnectWallet/index.tsx (2)

8-30: LGTM! Props updated for UI library v3.

The SwitchChainButton correctly uses isDisabled (line 25) and onPress (line 27) to align with the @kleros/ui-components-library v3 API.


32-44: LGTM! Props updated consistently.

The ConnectButton correctly uses isDisabled (line 38) and onPress (line 41), maintaining consistency with the UI library v3 API changes.

web/src/layout/Header/navbar/Explore.tsx (1)

15-42: LGTM! Clean migration to utility-based styling.

The component correctly:

  • Uses the cn utility for className composition
  • Implements active state logic based on pathname matching
  • Applies responsive styles with lg: breakpoint
  • Conditionally styles for mobile/desktop variants

The isActive helper (lines 18-19) properly handles both root path and nested routes.

web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)

8-11: LGTM! Button updated with onPress handler.

The DisconnectWalletButton correctly uses onPress (line 10) to align with the UI library v3 API.

web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1)

8-31: LGTM! Clean migration to Tailwind utilities.

The component has been cleanly migrated from styled-components to Tailwind utility classes. The layout structure and functionality are preserved, with straightforward className usage.

web/src/components/LightButton.tsx (1)

5-12: LGTM! Prop interface updated for UI library v3.

The rename from onClick to onPress aligns with the @kleros/ui-components-library v3 API. All call sites of LightButton have been successfully updated to use onPress.

web/src/layout/Header/MobileHeader.tsx (1)

27-33: LGTM! Clean migration to utility classes.

The refactor successfully replaces styled-components with Tailwind utilities. The arbitrary variant syntax [&_.button-svg]:mr-0 is correctly used to target nested SVG elements, and the switch from onClick to onPress aligns with the LightButton API update.

web/src/components/Overlay.tsx (1)

1-11: LGTM! Clean component migration.

The refactor from styled-components to a functional component with utility classes is well-executed. The cn utility properly merges default classes with the optional className prop, providing good API flexibility.

web/src/layout/Header/navbar/Menu/Help.tsx (1)

49-84: LGTM! Secure and accessible refactor.

The migration properly adds rel="noopener noreferrer" for external links, which prevents security vulnerabilities. The responsive layout with Tailwind utilities and hover effects using the group pattern are well-implemented.

web/src/layout/Header/index.tsx (1)

10-33: LGTM! Proper Tailwind v4 syntax and responsive design.

The migration correctly uses Tailwind v4 syntax with the important modifier at the end (sticky!) and appropriate responsive utilities. The CSS variables passed to StatusBanner's theme prop are correctly formatted as regular CSS custom properties.

web/src/layout/Header/navbar/index.tsx (1)

47-80: LGTM! Well-structured mobile navigation refactor.

The migration properly uses the cn utility for conditional class composition and maintains the overlay behavior with appropriate transitions. The switch from onClick to onPress is consistent with the LightButton API changes throughout the codebase.

web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)

27-27: No changes needed. The Settings component correctly implements the ISettings interface, which defines initialTab as an optional prop. While the component doesn't destructure initialTab, this is valid TypeScript—optional props don't require destructuring. DesktopHeader can pass it without error, and the component gracefully handles navigation via URL hash (location.hash.includes("#notifications")), providing the fallback behavior for tab selection. No breaking change exists.

web/src/layout/Header/DesktopHeader.tsx (1)

69-71: Verify extra props passed to modal components.

The code passes boolean state props (isDappListOpen, isHelpOpen, isSettingsOpen) to the modal components, but these props are not declared in the interface definitions (IDappList, IHelp, ISettings). This could indicate either:

  1. The components were updated to use these props but interfaces weren't updated
  2. These props are unnecessary and will be ignored

Additionally, as noted in Settings/index.tsx, the initialTab prop is being passed here but the Settings component no longer accepts it in its signature.

Verify the component signatures and prop usage:

#!/bin/bash
# Check DappList component signature
echo "=== DappList component ==="
rg -nP 'const DappList.*FC' -A 2 web/src/layout/Header/navbar/DappList

# Check Help component signature  
echo "=== Help component ==="
rg -nP 'const Help.*FC' -A 2 web/src/layout/Header/navbar/Menu/Help.tsx

# Check Settings component signature
echo "=== Settings component ==="
rg -nP 'const Settings.*FC' -A 2 web/src/layout/Header/navbar/Menu/Settings/index.tsx

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 16, 2025
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)
web/src/layout/Footer/index.tsx (1)

17-17: Consider cleaner margin control.

The [&_.button-svg]:mr-0 arbitrary selector overrides default margins from the LightButton component. If this pattern appears frequently, consider adding a margin control prop to LightButton instead of using arbitrary selectors.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75568be and 5e24ad3.

📒 Files selected for processing (2)
  • web/src/components/ExternalLink.tsx (0 hunks)
  • web/src/layout/Footer/index.tsx (1 hunks)
💤 Files with no reviewable changes (1)
  • web/src/components/ExternalLink.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
web/src/layout/Footer/index.tsx (1)
web/src/consts/socialmedia.tsx (1)
  • socialmedia (8-33)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
🔇 Additional comments (2)
web/src/layout/Footer/index.tsx (2)

8-8: LGTM!

The clsx import is correctly used for composing conditional class names in the Footer component.


28-32: Verify custom Tailwind colors are properly exposed by the library.

The Footer component uses custom color classes bg-klerosUIComponentsPrimaryPurple and dark:bg-klerosUIComponentsLightBlue that are sourced from the imported @kleros/ui-components-library. Confirm that the library's theme.css properly defines these as Tailwind --color-* theme variables (e.g., --color-klerosUIComponentsPrimaryPurple) rather than as regular CSS variables, to ensure the utility classes are generated correctly.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 17, 2025
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

♻️ Duplicate comments (1)
web/src/global.css (1)

1-5: [Duplicate] Fix @import order and remove redundant directive.

This issue has already been identified in a previous review. The @import "tailwindcss" at line 4 violates CSS specification because it appears after other at-rules, and having both @tailwind utilities and @import "tailwindcss" is redundant in Tailwind v4.

🧹 Nitpick comments (1)
web/src/pages/NewTransaction/Timeline.tsx (1)

24-27: Consider using exact matching instead of includes for route comparison.

The current route matching logic using includes() could unintentionally match overlapping paths if new routes are added later. While the current route set works correctly, a more robust approach would use exact matching or startsWith().

Apply this diff for a safer implementation:

-  const currentItemIndex = Object.entries(routeToIndexMap).reduce(
-    (acc, [route, index]) => (location.pathname.includes(route) ? index : acc),
-    0
-  );
+  const currentItemIndex = routeToIndexMap[location.pathname] ?? 0;

Or if you need partial matching:

-  const currentItemIndex = Object.entries(routeToIndexMap).reduce(
-    (acc, [route, index]) => (location.pathname.includes(route) ? index : acc),
-    0
-  );
+  const matchedRoute = Object.keys(routeToIndexMap).find(route => 
+    location.pathname === route || location.pathname.startsWith(route + '/')
+  );
+  const currentItemIndex = matchedRoute ? routeToIndexMap[matchedRoute] : 0;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e24ad3 and 0034dfd.

📒 Files selected for processing (5)
  • web/src/global.css (1 hunks)
  • web/src/pages/NewTransaction/HeroImage.tsx (1 hunks)
  • web/src/pages/NewTransaction/Timeline.tsx (1 hunks)
  • web/src/pages/NewTransaction/index.tsx (2 hunks)
  • web/src/styles/breakpoints.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-28T13:58:33.048Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx:44-46
Timestamp: 2024-11-28T13:58:33.048Z
Learning: In `web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx`, when checking `user.emailUpdateableAt`, it's acceptable to use the non-null assertion operator `!` due to type assertion issues preventing standard checks.

Applied to files:

  • web/src/pages/NewTransaction/index.tsx
🧬 Code graph analysis (2)
web/src/pages/NewTransaction/index.tsx (3)
web/src/styles/breakpoints.ts (1)
  • LG_BREAKPOINT (1-1)
web/src/consts/chains.ts (1)
  • DEFAULT_CHAIN (6-6)
web/src/components/EnsureAuth.tsx (1)
  • EnsureAuth (17-45)
web/src/pages/NewTransaction/HeroImage.tsx (2)
web/src/hooks/useToggleThemeContext.tsx (1)
  • useTheme (18-20)
web/src/styles/breakpoints.ts (1)
  • LG_BREAKPOINT (1-1)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
🔇 Additional comments (3)
web/src/pages/NewTransaction/HeroImage.tsx (1)

2-14: LGTM! Clean refactor to new theming approach.

The migration from styled-components theming to the custom theme hook is well-executed. The array destructuring pattern and simplified theme comparison make the code cleaner while maintaining the same functionality.

web/src/styles/breakpoints.ts (1)

1-1: This is a custom viewport breakpoint constant for layout comparisons, not a Tailwind configuration. The value of 900px is appropriate for this project's specific design needs and does not require alignment with Tailwind defaults, as no Tailwind configuration exists in the repository.

web/src/pages/NewTransaction/Timeline.tsx (1)

29-29: The Steps component usage requires verification against @kleros/ui-components-library v3.6.0 API documentation. Confirm that the component accepts the items array and currentItemIndex props with the current structure, as these prop names and their expected types are not verified in available documentation.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 17, 2025
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

♻️ Duplicate comments (1)
web/src/global.css (1)

1-5: Fix @import order and remove redundant directive.

This issue was previously identified and remains unresolved. The import structure has two critical problems:

  1. CSS spec violation: @import "tailwindcss" at line 4 violates the CSS specification because all @import rules must precede other at-rules (except @charset and @layer). Line 2's @tailwind utilities is an at-rule that appears before the import.

  2. Redundant directive: Per Tailwind CSS v4 documentation, @import "tailwindcss" replaces @tailwind base, @tailwind components, and @tailwind utilities. Having both is redundant and may cause conflicts.

🔎 Apply this fix:
-@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css";
-@tailwind utilities;
-@source "../../node_modules/@kleros/ui-components-library";
-@import "tailwindcss";
-@custom-variant dark (&:where(.dark, .dark *));
+@import "tailwindcss";
+@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css";
+@source "../../node_modules/@kleros/ui-components-library";
+@custom-variant dark (&:where(.dark, .dark *));

Based on Tailwind CSS v4 documentation and CSS specification.

🧹 Nitpick comments (1)
web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/CryptoSwap.tsx (1)

17-28: Consider aligning styling with GeneralEscrow for consistency.

The CryptoSwap component has minor styling differences compared to GeneralEscrow:

  • Line 17: justify-center is present here but absent in GeneralEscrow
  • Line 27: px-2 padding is present here but absent in GeneralEscrow

Since both components serve the same purpose as escrow type options, they should have consistent styling.

🔎 Suggested alignment:

Option 1: Remove extra styles from CryptoSwap to match GeneralEscrow:

-    <div className="flex flex-col gap-6 justify-center">
+    <div className="flex flex-col gap-6">
       <Card
         className={cn(
           "flex h-24 w-24 items-center justify-center cursor-pointer rounded-[20px]!",
           selected && "border border-klerosUIComponentsPrimaryBlue"
         )}
         onClick={handleSelect}
       >
         <Logo className="fill-klerosUIComponentsSecondaryPurple" />
       </Card>
-      <p className="flex flex-wrap w-24 m-0 text-center px-2">Crypto Swap</p>
+      <p className="flex flex-wrap w-24 m-0 text-center">Crypto Swap</p>
     </div>

Option 2: Add the same styles to GeneralEscrow if the extra spacing is intentional.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d810250 and 01d2991.

📒 Files selected for processing (12)
  • web/src/components/StyledIcons/ClosedCircleIcon.tsx (0 hunks)
  • web/src/global.css (1 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/CryptoSwap.tsx (1 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/GeneralEscrow.tsx (1 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/index.tsx (1 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/Info.tsx (1 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx (1 hunks)
  • web/src/pages/NewTransaction/Header.tsx (1 hunks)
  • web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx (5 hunks)
  • web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx (1 hunks)
  • web/src/pages/NewTransaction/NavigationButtons/PreviousButton.tsx (1 hunks)
  • web/src/pages/NewTransaction/NavigationButtons/index.tsx (1 hunks)
💤 Files with no reviewable changes (1)
  • web/src/components/StyledIcons/ClosedCircleIcon.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-11-28T13:58:33.048Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx:44-46
Timestamp: 2024-11-28T13:58:33.048Z
Learning: In `web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx`, when checking `user.emailUpdateableAt`, it's acceptable to use the non-null assertion operator `!` due to type assertion issues preventing standard checks.

Applied to files:

  • web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx
  • web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx
  • web/src/pages/NewTransaction/NavigationButtons/index.tsx
  • web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx
  • web/src/pages/NewTransaction/NavigationButtons/PreviousButton.tsx
📚 Learning: 2024-10-08T16:23:56.291Z
Learnt from: kemuru
Repo: kleros/escrow-v2 PR: 60
File: web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx:180-180
Timestamp: 2024-10-08T16:23:56.291Z
Learning: The `refetchAllowance` function call is necessary in the `DepositPaymentButton` component to ensure the frontend updates correctly after an approval action.

Applied to files:

  • web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx
📚 Learning: 2024-06-11T17:14:13.327Z
Learnt from: kemuru
Repo: kleros/escrow-v2 PR: 60
File: web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx:63-64
Timestamp: 2024-06-11T17:14:13.327Z
Learning: Errors in the `useContractRead` hook for ERC20 token allowance checks in the `DepositPaymentButton` component are managed by the `wrapWithToast()` function, which logs errors in a notification popup. Additionally, the quantity for the approval is pre-validated and stored in the context of the NewTransactionContext.

Applied to files:

  • web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx
🧬 Code graph analysis (4)
web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/GeneralEscrow.tsx (2)
web/src/context/NewTransactionContext.tsx (1)
  • useNewTransactionContext (56-60)
web/src/utils/index.ts (1)
  • cn (41-43)
web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/CryptoSwap.tsx (2)
web/src/context/NewTransactionContext.tsx (1)
  • useNewTransactionContext (56-60)
web/src/utils/index.ts (1)
  • cn (41-43)
web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx (3)
web/src/context/NewTransactionContext.tsx (1)
  • useNewTransactionContext (56-60)
web/src/utils/bufferRules.ts (1)
  • pickBufferFor (8-12)
web/src/utils/validateAddress.ts (1)
  • ethAddressPattern (1-1)
web/src/pages/NewTransaction/NavigationButtons/PreviousButton.tsx (1)
web/src/utils/index.ts (1)
  • isEmpty (10-10)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
🔇 Additional comments (10)
web/src/pages/NewTransaction/Header.tsx (1)

8-8: LGTM! Clean migration to Tailwind v4.

The CSS variable syntax text-(length:--spacing-fluid-20-24) correctly uses Tailwind v4's type-hint syntax to disambiguate the variable's intended use as a font-size value. The responsive utilities and layout classes are well-structured.

web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/index.tsx (1)

9-15: LGTM!

Clean migration from styled-components to Tailwind utility classes. The flexbox layout is appropriate and the structure is maintained.

web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/GeneralEscrow.tsx (1)

17-28: LGTM!

Well-executed migration to Tailwind v4 and the UI components library. The conditional border styling using cn utility is clean, and the Tailwind v4 important modifier syntax (rounded-[20px]!) is correct.

web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/Info.tsx (1)

9-23: LGTM!

Clean refactor removing the styled wrapper. The responsive width utility (lg:w-fluid-342-618) correctly references the custom fluid spacing token defined in global.css.

web/src/pages/NewTransaction/EscrowDetails/TypeOfEscrow/EscrowOptions/index.tsx (1)

7-10: LGTM!

Straightforward migration from styled-components to Tailwind utility classes. The flexbox layout with centered content and spacing is appropriate for displaying escrow options.

web/src/pages/NewTransaction/NavigationButtons/PreviousButton.tsx (1)

13-18: LGTM! Clean migration to utility classes.

The conditional visibility pattern using className={isEmpty(prevRoute) ? "hidden" : "flex"} is appropriate. The Button component correctly uses the new API (onPress instead of onClick) from @kleros/ui-components-library v3.

web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx (2)

46-52: LGTM! Formatting improvements.

The useMemo expressions are reformatted for better readability with no functional changes.


194-206: LGTM! Button API correctly updated.

The Button component now uses isDisabled and onPress props, correctly aligning with @kleros/ui-components-library v3 API changes.

web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx (1)

141-146: LGTM! Button API correctly updated.

The Button component props have been correctly migrated to the v3 API: disabledisDisabled and onClickonPress.

web/src/pages/NewTransaction/NavigationButtons/index.tsx (1)

13-20: LGTM! Clean migration to Tailwind utility classes.

The navigation buttons container uses appropriate Tailwind classes for a responsive, centered button layout. The conditional rendering logic correctly shows either the DepositPaymentButton or NextButton based on the current route.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 18, 2025
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

♻️ Duplicate comments (1)
web/src/global.css (1)

1-5: CSS import order and redundancy issues already flagged.

The critical issues with the import structure (CSS spec violation for @import order and redundant @tailwind utilities directive) have already been identified in the previous review comment with a correct fix provided.

🧹 Nitpick comments (1)
web/src/pages/NewTransaction/EscrowDetails/Title/index.tsx (1)

10-12: Optional: Consider simplifying by passing setEscrowTitle directly.

The handleWrite wrapper doesn't add any transformation or validation, so you could pass setEscrowTitle directly to the TextField's onChange prop.

🔎 Apply this diff to simplify:
-  const handleWrite = (value: string) => {
-    setEscrowTitle(value);
-  };
-
   return (
     <div className="flex flex-col items-center">
       <Header text="Title" />
       <TextField
         className="w-[84vw] lg:w-fluid-342-500"
         value={escrowTitle}
-        onChange={handleWrite}
+        onChange={setEscrowTitle}
         placeholder="e.g. Escrow with John"
       />
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01d2991 and baa32a3.

📒 Files selected for processing (3)
  • web/src/global.css (1 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/Title/TextField.tsx (0 hunks)
  • web/src/pages/NewTransaction/EscrowDetails/Title/index.tsx (1 hunks)
💤 Files with no reviewable changes (1)
  • web/src/pages/NewTransaction/EscrowDetails/Title/TextField.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-28T13:58:33.048Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx:44-46
Timestamp: 2024-11-28T13:58:33.048Z
Learning: In `web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx`, when checking `user.emailUpdateableAt`, it's acceptable to use the non-null assertion operator `!` due to type assertion issues preventing standard checks.

Applied to files:

  • web/src/pages/NewTransaction/EscrowDetails/Title/index.tsx
🧬 Code graph analysis (1)
web/src/pages/NewTransaction/EscrowDetails/Title/index.tsx (1)
web/src/context/NewTransactionContext.tsx (1)
  • useNewTransactionContext (56-60)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - kleros-escrow-v2
  • GitHub Check: Header rules - kleros-escrow-v2
  • GitHub Check: Pages changed - kleros-escrow-v2
🔇 Additional comments (2)
web/src/global.css (2)

7-150: Well-structured global styles and theme variables.

The implementation of CSS variables, responsive spacing utilities, dark mode overrides, typography, and custom scrollbar styling is solid:

  • Comprehensive color and spacing token system with fluid responsive utilities using clamp()
  • Proper dark mode variable overrides scoped to .dark class
  • Cross-browser scrollbar styling with webkit pseudo-elements and scrollbar-width fallback
  • Standard CSS reset pattern and consistent typography referencing UI library theme variables

Once the import order issue (lines 1-5) is resolved, this provides a clean foundation for the Tailwind migration.


65-69: Ensure Open Sans font is properly loaded.

The body style references "Open Sans", but there's no direct @font-face declaration or font import in this file. The global.css imports theme.css from @kleros/ui-components-library (which presumably provides font loading), but this library is not listed in package.json dependencies or present in node_modules. Verify that the library is properly declared as a dependency or add explicit font loading (e.g., via Google Fonts link or @font-face) to ensure consistent typography instead of relying on the generic sans-serif fallback.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 18, 2025
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: 3

♻️ Duplicate comments (1)
web/src/global.css (1)

1-5: Fix @import order and remove redundant directive.

This issue has already been flagged: the @import "tailwindcss" at line 4 violates CSS specification (must precede other at-rules), and having both @tailwind utilities (line 2) and @import "tailwindcss" (line 4) is redundant per Tailwind v4 documentation.

Please refer to the previous review comment for the recommended fix.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between baa32a3 and bc774cb.

📒 Files selected for processing (9)
  • web/src/global.css (1 hunks)
  • web/src/hooks/useIsDesktop.tsx (1 hunks)
  • web/src/pages/NewTransaction/Terms/Deliverable/index.tsx (2 hunks)
  • web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx (2 hunks)
  • web/src/pages/NewTransaction/Terms/Payment/ToDivider.tsx (1 hunks)
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/AmountField.tsx (0 hunks)
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/Token.tsx (0 hunks)
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/index.tsx (2 hunks)
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/index.tsx (1 hunks)
💤 Files with no reviewable changes (2)
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/AmountField.tsx
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/Token.tsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-11-28T13:58:33.048Z
Learnt from: Harman-singh-waraich
Repo: kleros/escrow-v2 PR: 86
File: web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx:44-46
Timestamp: 2024-11-28T13:58:33.048Z
Learning: In `web/src/pages/NewTransaction/NavigationButtons/NextButton.tsx`, when checking `user.emailUpdateableAt`, it's acceptable to use the non-null assertion operator `!` due to type assertion issues preventing standard checks.

Applied to files:

  • web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/index.tsx
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/index.tsx
📚 Learning: 2024-10-08T16:23:56.291Z
Learnt from: kemuru
Repo: kleros/escrow-v2 PR: 60
File: web/src/pages/NewTransaction/NavigationButtons/DepositPaymentButton.tsx:63-64
Timestamp: 2024-10-08T16:23:56.291Z
Learning: Errors in the `useContractRead` hook for ERC20 token allowance checks in the `DepositPaymentButton` component are managed by the `wrapWithToast()` function, which logs errors in a notification popup. Additionally, the quantity for the approval is pre-validated and stored in the context of the NewTransactionContext.

Applied to files:

  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/index.tsx
  • web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/index.tsx
🧬 Code graph analysis (1)
web/src/hooks/useIsDesktop.tsx (1)
web/src/styles/breakpoints.ts (1)
  • LG_BREAKPOINT (1-1)
🪛 Biome (2.1.2)
web/src/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

🔇 Additional comments (6)
web/src/pages/NewTransaction/Terms/Deliverable/index.tsx (1)

46-78: LGTM!

The migration from styled-components to Tailwind utility classes is well-executed. All functional logic (handleWrite, handleAttachFile, conditional rendering) remains unchanged, with only layout and styling updated to use Tailwind classes and responsive width utilities.

web/src/global.css (1)

7-153: LGTM!

The theme configuration, CSS variables, typography, and utility styles are comprehensive and well-structured. The dark mode support, responsive spacing utilities, and custom scrollbar styling provide a solid foundation for the Tailwind migration.

web/src/pages/NewTransaction/Terms/Payment/DestinationAddress.tsx (1)

2-2: Verify TextField onChange API signature.

The migration from styled Field to TextField looks clean, and all validation logic remains intact. However, the specific onChange callback signature for @kleros/ui-components-library TextField needs verification to ensure it accepts a value parameter rather than a synthetic event.

web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/index.tsx (1)

32-38: LGTM! Clean migration to Tailwind.

The replacement of the styled Container with a plain div using Tailwind utility classes (flex flex-col items-center) is straightforward and preserves the intended vertical flexbox layout with centered items.

web/src/pages/NewTransaction/Terms/Payment/TokenTransaction/TokenAndAmount/index.tsx (1)

2-2: Verify library API usage with v3.6.0.

Please confirm that the NumberField and DropdownSelect components from @kleros/ui-components-library v3.6.0 support:

  • The formatOptions prop structure used on lines 19-23
  • The distinction between selectedKey (controlled) vs defaultSelectedKey (uncontrolled)
  • Availability of label or aria-label props for accessibility
  • The callback prop pattern for DropdownSelect
@kleros/ui-components-library v3.6.0 NumberField DropdownSelect API documentation

Also applies to: 14-32

web/src/hooks/useIsDesktop.tsx (1)

4-8: Breakpoint refactoring looks good.

The refactoring correctly centralizes the breakpoint constant. The new LG_BREAKPOINT = 900 matches the previous BREAKPOINT_LANDSCAPE = 900, so the desktop detection behavior remains unchanged. The useMemo implementation with the correct dependency array is solid.

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.

Frontend migration to the major update of @kleros/ui-components-library v3 with Tailwind

2 participants