Skip to content

Add Use sorted classes biome rule - #4

Merged
kovrichard merged 4 commits into
mainfrom
use-sorted-classes
Oct 18, 2025
Merged

Add Use sorted classes biome rule#4
kovrichard merged 4 commits into
mainfrom
use-sorted-classes

Conversation

@matekissdev

@matekissdev matekissdev commented Oct 18, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Style

    • Widespread visual refinements: spacing, alignment, typography, and minor icon/button sizing adjustments across layouts, pages, and UI components for more consistent presentation.
  • Bug Fixes

    • Improved link behavior and security for the site badge by composing campaign params and adding safer link attributes.
  • Chores

    • Added a new linter rule to enforce sorted class ordering across the codebase.

@matekissdev matekissdev self-assigned this Oct 18, 2025
@vercel

vercel Bot commented Oct 18, 2025

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
catalyst Ignored Ignored Oct 18, 2025 2:06pm

💡 Enable Vercel Agent with $100 free credit for automated AI reviews

@coderabbitai

coderabbitai Bot commented Oct 18, 2025

Copy link
Copy Markdown

Walkthrough

Adds a Biome linter nursery rule linter.rules.nursery.useSortedClasses = "error" and applies widespread Tailwind utility-class reordering across layouts, pages, and UI components; a small href composition change and rel="noopener noreferrer" were added to a badge component.

Changes

Cohort / File(s) Summary
Configuration
biome.json
Added linter.rules.nursery.useSortedClasses set to "error".
Root & App Layouts
src/app/layout.tsx, src/app/(protected)/layout.tsx, src/app/(public)/layout.tsx, src/app/(public)/page.tsx, src/app/(public)/privacy-policy/page.tsx, src/app/(protected)/dashboard/page.tsx, src/app/(protected)/settings/page.tsx
Reordered Tailwind utility classes in layout and page components; no control-flow or API changes.
Auth UI
src/components/auth/*
src/components/auth/auth-card.tsx, src/components/auth/login-form.tsx, src/components/auth/register-form.tsx, src/components/auth/oauth-button.tsx, src/components/auth/last-used-indicator.tsx
Reordered utility-class tokens on inputs, buttons, error spans, and indicators; presentation-only.
Header / Navigation / Sidebar
src/components/top-menu.tsx, src/components/sidebar/*, src/components/sidebar/app-sidebar.tsx, src/components/sidebar/profile-menu.tsx, src/components/ui/sidebar.tsx
Reordered class lists for header, top menu and sidebar components; preserved behavior and exported APIs.
Notifications & Actions
src/components/notification-item.tsx, src/components/notification-menu.tsx, src/components/mark-all-as-read-button.tsx
Reordered spacing/typography classes in notification items, menu and action buttons; no semantic changes.
Cookie & Footer
src/components/cookie-popup.tsx, src/components/footer/catalyst-badge.tsx
Cookie popup: class reordering (presentation-only). Catalyst badge: builds queryParams to compose href, adds rel="noopener noreferrer", and reorders styling classes.
Settings Forms
src/components/settings/delete-account-form.tsx, src/components/settings/password-form.tsx
Error and typography class token reordering; no logic changes.
UI Primitives
src/components/ui/*
includes alert-dialog.tsx, card.tsx, dropdown-menu.tsx, input.tsx, popover.tsx, sheet.tsx, tooltip.tsx, diagonal-edge.tsx, shiny-border.tsx
Reordered animation, positioning and typography utility classes across core primitives; behavior and public APIs unchanged.
Misc Components
src/components/*
Numerous additional components received class-token reordering to conform to sorting rule; no new control flow or API changes.

Sequence Diagram(s)

sequenceDiagram
  participant U as User (renders page)
  participant C as CatalystBadge component
  participant Q as queryParams builder
  U->>C: render
  C->>Q: derive params (source, medium, campaign)
  Q-->>C: return query string
  C->>U: render `<a href="...?[query]" rel="noopener noreferrer">`
  note right of C: Most components only reorder Tailwind classes (presentation-only)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I tidy classes, hop and sort,
Linter hums — a careful court.
Links stitched neat with safe rel,
Tailwind rows now sing so well.
I munch a bug, then bound and twirl. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Add Use sorted classes biome rule" accurately describes the primary objective of the pull request, which is to enable the useSortedClasses linting rule in the biome configuration. While the bulk of the changeset consists of reordering CSS utility classes throughout the codebase to comply with this new rule, the title appropriately captures the core action: adding/enabling a new biome linter rule. The title is clear, concise, and specific enough for a reviewer scanning history to understand that this PR introduces a new linting requirement for sorted classes.
✨ Finishing touches
  • 📝 Docstrings were successfully generated.
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch use-sorted-classes

📜 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 442c264 and d8f3e61.

📒 Files selected for processing (1)
  • src/components/footer/catalyst-badge.tsx (1 hunks)
🔇 Additional comments (3)
src/components/footer/catalyst-badge.tsx (3)

14-15: Excellent implementation of defensive query string construction!

The use of .filter(Boolean).join("&") elegantly handles the empty source case on initial render, preventing any stray "&" characters. This correctly addresses the previous review feedback.

Also applies to: 18-18


20-20: Good security practice!

Adding rel="noopener noreferrer" prevents reverse tabnabbing and properly addresses the security concern from the previous review.


21-21: Tailwind class reordering applied correctly.

The className has been updated to comply with the new Biome linter rule useSortedClasses. The styling remains functionally equivalent.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (3)
src/components/cookie-popup.tsx (2)

65-76: Optional: dialog semantics and cleanup for timers.

Consider basic ARIA for better a11y and clear timeouts to avoid setState-after-unmount in edge cases.

-    <div
-      className={cn(
+    <div
+      role="dialog"
+      aria-labelledby="cookie-consent-title"
+      className={cn(
         "fixed right-4 bottom-4 z-50 max-w-[calc(100vw-2rem)] rounded-lg border bg-background p-4 shadow-lg sm:max-w-md",
         "cookie-popup-bottom",
         isExiting && "exiting"
       )}
     >
-      <div className="mb-2 flex items-center gap-2">
+      <div className="mb-2 flex items-center gap-2">
         <Cookie />
-        <h4 className="font-semibold">Cookie consent</h4>
+        <h4 id="cookie-consent-title" className="font-semibold">Cookie consent</h4>
       </div>
-      <div className="mb-3 text-sm">
+      <div className="mb-3 text-sm">
         <p>This website uses cookies to improve the user experience.</p>
       </div>

Outside this hunk, store/clear timer ids:

// near line 33
const exitTimer = useRef<number | null>(null);

// replace setTimeout(...) with:
exitTimer.current = window.setTimeout(() => { setIsOpen(false); setIsExiting(false); }, 300);

// in useEffect cleanup:
useEffect(() => {
  const accepted = localStorage.getItem("cookie-popup-accepted");
  if (accepted !== "true") {
    const openTimer = window.setTimeout(() => setIsOpen(true), 1000);
    return () => window.clearTimeout(openTimer);
  }
  return;
}, []);

useEffect(() => {
  return () => { if (exitTimer.current) window.clearTimeout(exitTimer.current); };
}, []);

77-87: Border added on “Reject” only — confirm intent.

variant="ghost" typically has no border; adding border only on Reject changes emphasis vs Accept. Ensure this visual change is intentional; otherwise align both buttons.

-        <Button onClick={handleReject} variant="ghost" className="w-full border sm:w-28">
+        <Button onClick={handleReject} variant="ghost" className="w-full sm:w-28">
           Reject
         </Button>

—or add a consistent border to Accept as well.

src/components/sidebar/profile-menu.tsx (1)

57-64: Consistency: include noreferrer on internal target="_blank" too (optional).

You already use rel="noopener"; consider noreferrer for consistency and to avoid referrer leakage (even to same-origin).

-          rel="noopener"
+          rel="noopener noreferrer"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17c196e and a533e3f.

📒 Files selected for processing (33)
  • biome.json (1 hunks)
  • src/app/(protected)/dashboard/page.tsx (1 hunks)
  • src/app/(protected)/layout.tsx (1 hunks)
  • src/app/(protected)/settings/page.tsx (1 hunks)
  • src/app/(public)/layout.tsx (2 hunks)
  • src/app/(public)/page.tsx (6 hunks)
  • src/app/(public)/privacy-policy/page.tsx (16 hunks)
  • src/app/layout.tsx (1 hunks)
  • src/components/auth/auth-card.tsx (1 hunks)
  • src/components/auth/last-used-indicator.tsx (1 hunks)
  • src/components/auth/login-form.tsx (2 hunks)
  • src/components/auth/oauth-button.tsx (1 hunks)
  • src/components/auth/register-form.tsx (3 hunks)
  • src/components/cookie-popup.tsx (1 hunks)
  • src/components/footer/catalyst-badge.tsx (1 hunks)
  • src/components/mark-all-as-read-button.tsx (1 hunks)
  • src/components/notification-item.tsx (1 hunks)
  • src/components/notification-menu.tsx (2 hunks)
  • src/components/settings/delete-account-form.tsx (1 hunks)
  • src/components/settings/password-form.tsx (2 hunks)
  • src/components/sidebar/app-sidebar.tsx (1 hunks)
  • src/components/sidebar/profile-menu.tsx (1 hunks)
  • src/components/top-menu.tsx (1 hunks)
  • src/components/ui/alert-dialog.tsx (4 hunks)
  • src/components/ui/card.tsx (2 hunks)
  • src/components/ui/diagonal-edge.tsx (1 hunks)
  • src/components/ui/dropdown-menu.tsx (5 hunks)
  • src/components/ui/input.tsx (1 hunks)
  • src/components/ui/popover.tsx (1 hunks)
  • src/components/ui/sheet.tsx (4 hunks)
  • src/components/ui/shiny-border.tsx (2 hunks)
  • src/components/ui/sidebar.tsx (12 hunks)
  • src/components/ui/tooltip.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (11)
src/components/ui/card.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/components/notification-menu.tsx (1)
src/components/mark-all-as-read-button.tsx (1)
  • MarkAllAsReadButton (7-20)
src/components/ui/dropdown-menu.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/components/notification-item.tsx (2)
src/lib/actions/notifications.ts (1)
  • readNotification (7-9)
src/lib/utils.ts (1)
  • formatTimeAgo (25-27)
src/app/(public)/page.tsx (3)
src/components/animations/scroll-reveal.tsx (1)
  • ScrollReveal (16-70)
src/components/animations/scroll-float.tsx (1)
  • ScrollFloat (19-173)
src/components/animations/cursor-float.tsx (1)
  • CursorFloat (14-174)
src/components/ui/sheet.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/app/layout.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/components/ui/diagonal-edge.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/components/ui/shiny-border.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/components/ui/sidebar.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
src/components/ui/alert-dialog.tsx (1)
src/lib/utils.ts (1)
  • cn (6-8)
🔇 Additional comments (38)
src/components/settings/delete-account-form.tsx (1)

37-38: LGTM! Class reordering aligns with the new linter rule.

The Tailwind utility classes have been correctly reordered to comply with the useSortedClasses Biome rule. These changes are purely presentational and don't affect the rendered output or functionality.

src/components/auth/oauth-button.tsx (1)

17-17: LGTM! Class reordering applied correctly.

The Tailwind classes have been reordered to comply with the new useSortedClasses Biome linter rule. All utility classes remain present with no functional changes.

src/components/ui/alert-dialog.tsx (4)

23-23: LGTM: Animation classes reordered consistently.

The reordering of Tailwind utility classes complies with the new Biome rule and maintains identical functionality.


41-41: LGTM: Comprehensive class reordering applied.

The extensive reordering of animation, positioning, and layout classes adheres to the linting rule without altering the component's visual appearance or behavior.


86-86: LGTM: Typography classes ordered logically.

The reordering places font-weight before font-size, following a consistent pattern.


99-99: LGTM: Text utilities ordered consistently.

The reordering places color utility before size utility, maintaining consistency with the enforced linting rule.

src/components/sidebar/app-sidebar.tsx (1)

26-26: LGTM!

Class reordering aligns with the new useSortedClasses rule. No functional impact.

src/components/ui/diagonal-edge.tsx (1)

88-88: LGTM!

Class reordering for linter compliance. No functional impact.

src/components/mark-all-as-read-button.tsx (1)

14-14: LGTM!

Class reordering for linter compliance. No functional impact.

src/components/auth/login-form.tsx (1)

62-62: LGTM!

Error message class reordering for linter compliance. No functional impact.

Also applies to: 74-74

src/components/ui/input.tsx (1)

11-11: LGTM!

Class reordering within the Input component for linter compliance. No functional impact.

src/components/top-menu.tsx (1)

6-6: LGTM!

Class reordering for linter compliance. No functional impact.

src/components/auth/register-form.tsx (1)

63-63: LGTM!

Error message class reordering for linter compliance. Consistent with the changes in login-form.tsx. No functional impact.

Also applies to: 75-75, 87-87

biome.json (1)

36-38: Confirm severity level choice for experimental rule.

Biome's "nursery" rules are experimental and not subject to semantic versioning, meaning their diagnostic severity and behavior may change. Setting useSortedClasses to "error" is restrictive for an unstable rule and may require updates if the rule changes in a future Biome release.

Consider whether "warn" severity is more appropriate initially, or confirm the team is prepared to adjust this configuration as the rule evolves.

src/components/auth/auth-card.tsx (1)

41-41: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.

src/components/auth/last-used-indicator.tsx (1)

28-28: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.

src/app/layout.tsx (1)

54-54: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.

src/components/settings/password-form.tsx (1)

72-92: LGTM! Class reordering applied correctly.

The Tailwind utility classes in all error message spans have been consistently reordered to comply with the useSortedClasses rule without altering functionality.

src/app/(protected)/settings/page.tsx (1)

26-26: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.

src/components/ui/popover.tsx (1)

25-26: LGTM! Class reordering applied correctly.

The Tailwind utility classes, including animation and state-based modifiers, have been reordered to comply with the useSortedClasses rule without altering functionality.

src/components/ui/card.tsx (2)

32-32: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.


45-45: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.

src/components/ui/dropdown-menu.tsx (5)

53-53: LGTM! Class reordering applied correctly.

The Tailwind utility classes, including animation and state-based modifiers, have been reordered to comply with the useSortedClasses rule without altering functionality.


72-72: LGTM! Class reordering applied correctly.

The Tailwind utility classes, including animation and state-based modifiers, have been reordered to comply with the useSortedClasses rule without altering functionality.


111-111: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.


136-136: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.


161-161: LGTM! Class reordering applied correctly.

The Tailwind utility classes have been reordered to comply with the useSortedClasses rule without altering functionality.

src/app/(protected)/layout.tsx (1)

21-23: LGTM — class sorting only.

Utility order normalized; no behavior changes.

src/app/(protected)/dashboard/page.tsx (1)

3-6: LGTM — presentational reorder.

Only Tailwind class order changes; structure and content unchanged.

src/components/ui/tooltip.tsx (1)

24-24: LGTM! Tailwind class reordering aligns with the new linter rule.

The className string has been reordered to comply with the useSortedClasses rule without altering functionality or visual appearance.

src/components/ui/sheet.tsx (1)

26-26: LGTM! Consistent class reordering across sheet components.

All className updates maintain the same styling while conforming to the useSortedClasses linter rule. No functional changes detected.

Also applies to: 72-72, 111-111, 124-124

src/components/notification-item.tsx (1)

22-22: LGTM! Tailwind classes reordered consistently.

The className updates across the notification item component maintain identical styling and behavior while conforming to the new linter rule.

Also applies to: 25-25, 28-28, 31-31, 38-38

src/components/notification-menu.tsx (1)

23-23: LGTM! Notification menu classes reordered appropriately.

All className changes maintain the same visual presentation and functionality while adhering to the useSortedClasses rule.

Also applies to: 30-32, 42-42, 48-48

src/app/(public)/privacy-policy/page.tsx (1)

25-26: LGTM! Typography and layout classes reordered consistently throughout.

The privacy policy page has been updated with consistent className ordering for all headings, lists, and containers. All changes are presentational and maintain the same visual layout and content.

Also applies to: 38-39, 45-47, 146-148, 154-154, 164-165, 184-184, 191-191, 207-207, 214-214, 237-237, 282-284, 350-350, 388-388, 402-402, 422-422, 443-443, 449-449, 455-456, 460-460, 467-467, 474-474, 488-488, 498-498, 512-515

src/components/ui/shiny-border.tsx (1)

14-14: LGTM! Shiny border component classes reordered correctly.

All className updates maintain the same visual effect and animation behavior while conforming to the useSortedClasses rule.

Also applies to: 16-16, 19-19, 21-21, 38-38

src/app/(public)/layout.tsx (1)

16-17: LGTM! Public layout classes reordered appropriately.

The className updates for the layout containers, header, and footer maintain identical styling while adhering to the new linter rule. No functional changes to the layout structure or authentication logic.

Also applies to: 20-20, 39-39

src/components/ui/sidebar.tsx (1)

200-200: LGTM! Comprehensive sidebar class reordering completed successfully.

All className updates across the sidebar components maintain identical functionality, state management, and visual presentation while conforming to the useSortedClasses rule. The complex sidebar logic remains intact.

Also applies to: 209-209, 219-219, 280-280, 283-283, 299-299, 394-394, 415-417, 547-549, 569-569, 598-598, 605-605, 623-623, 656-656

src/app/(public)/page.tsx (1)

87-219: LGTM! Class reordering aligns perfectly with the PR objective.

All Tailwind CSS utility class reorderings in this file are consistent with enabling the useSortedClasses Biome linter rule. The changes are purely cosmetic, maintain the same visual output, and improve code consistency across the codebase.

Comment thread src/components/footer/catalyst-badge.tsx
Comment thread src/components/sidebar/profile-menu.tsx
@sonarqubecloud

Copy link
Copy Markdown

@kovrichard
kovrichard merged commit 61eb995 into main Oct 18, 2025
4 checks passed
@kovrichard
kovrichard deleted the use-sorted-classes branch October 18, 2025 14:13
@coderabbitai

coderabbitai Bot commented Oct 22, 2025

Copy link
Copy Markdown

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #5

coderabbitai Bot added a commit that referenced this pull request Oct 22, 2025
Docstrings generation was requested by @kovrichard.

* #4 (comment)

The following files were modified:

* `src/app/(protected)/dashboard/page.tsx`
* `src/app/(protected)/layout.tsx`
* `src/app/(protected)/settings/page.tsx`
* `src/app/(public)/layout.tsx`
* `src/app/(public)/page.tsx`
* `src/app/(public)/privacy-policy/page.tsx`
* `src/app/layout.tsx`
* `src/components/auth/auth-card.tsx`
* `src/components/auth/last-used-indicator.tsx`
* `src/components/auth/login-form.tsx`
* `src/components/auth/oauth-button.tsx`
* `src/components/auth/register-form.tsx`
* `src/components/cookie-popup.tsx`
* `src/components/footer/catalyst-badge.tsx`
* `src/components/mark-all-as-read-button.tsx`
* `src/components/notification-item.tsx`
* `src/components/notification-menu.tsx`
* `src/components/settings/delete-account-form.tsx`
* `src/components/settings/password-form.tsx`
* `src/components/sidebar/app-sidebar.tsx`
* `src/components/sidebar/profile-menu.tsx`
* `src/components/top-menu.tsx`
* `src/components/ui/alert-dialog.tsx`
* `src/components/ui/card.tsx`
* `src/components/ui/diagonal-edge.tsx`
* `src/components/ui/dropdown-menu.tsx`
* `src/components/ui/input.tsx`
* `src/components/ui/popover.tsx`
* `src/components/ui/sheet.tsx`
* `src/components/ui/shiny-border.tsx`
* `src/components/ui/sidebar.tsx`
* `src/components/ui/tooltip.tsx`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants