Enhance navigation components and improve UI consistency#3
Conversation
- Added "use client" directive to several components for client-side rendering. - Reorganized imports for better readability and consistency across components. - Enhanced class names and data attributes for better styling and accessibility. - Updated dialog, context menu, command, and dropdown components to streamline props and improve functionality. - Adjusted CSS variables for accent colors to ensure better visual consistency. - Removed unnecessary comments and cleaned up code formatting for clarity.
…components - Updated imports to use consistent semicolon usage in multiple files. - Refactored Textarea, ToggleGroup, Toggle, Tooltip, and other components for improved readability and consistency. - Adjusted spacing and indentation for better alignment and clarity. - Ensured all components maintain a consistent structure and style. - Minor adjustments to error handling and schema definitions for better clarity.
|
Warning Review limit reached
More reviews will be available in 18 minutes and 5 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR adds an auth middleware and sidebar navigation/logout changes, updates many shared UI wrappers and widgets for client usage and prop-order behavior, and refreshes project config, styling, and dependency versions. ChangesAuth and shell
Shared UI system and config
Sequence Diagram(s)No additional diagrams. Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Possibly related PRs
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
|
React Doctor found 64 issues in 24 files · 3 errors & 61 warnings · score 58 / 100 (Critical) · vs Errors
61 warnings
11 more warnings not shown. Reviewed by React Doctor for commit |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 19
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/sidebar/nav-user.tsx`:
- Around line 25-34: The handleLogout function currently calls
authClient.signOut with only fetchOptions.onSuccess and always awaits then
navigates; update it to handle failures by either adding fetchOptions.onError to
authClient.signOut or wrapping the await in a try/catch: on error call
toast.error with a clear message (and do not call navigate) and optionally log
the error, and on success keep toast.success and navigate to "/sign-in";
reference handleLogout, authClient.signOut, fetchOptions.onError, toast.error,
toast.success and navigate when making the change.
In `@src/components/ui/alert-dialog.tsx`:
- Around line 168-172: The wrapper components (AlertDialogCancel, ComboboxClear,
ComboboxInput) currently pass render={...} before {...props}, allowing consumer
props to override the wrapper's render and in ComboboxInput to bypass the
wrapper's disabled wiring into InputGroupInput; fix this by reordering so you
spread {...props} first and then set the wrapper-owned render prop last (and
ensure the wrapper-owned disabled wiring for InputGroupInput is also applied
after spreading props) so the wrapper's render/disabled cannot be overridden by
consumer-supplied props.
In `@src/components/ui/alert.tsx`:
- Around line 28-32: The wrapper currently spreads {...props} after setting
role="alert" in the Alert component (see alertVariants and cn usage in
src/components/ui/alert.tsx), allowing consumers to override and remove the
built-in role; move the {...props} spread earlier (or explicitly reassign
role="alert" after spreading props) so role="alert" cannot be overridden by
incoming props and screen-reader semantics are preserved.
In `@src/components/ui/aspect-ratio.tsx`:
- Around line 12-17: The component currently spreads {...props} after supplying
an inline style with "--ratio", which allows a caller's style to overwrite and
drop the computed ratio; fix it by merging styles so the computed "--ratio" is
preserved—e.g., build the final style from props.style and then set the
"--ratio" key from the local ratio variable (or spread props without style and
pass a merged style object), updating the AspectRatio component in
aspect-ratio.tsx to use props.style merged with "--ratio" instead of letting
{...props} clobber it.
In `@src/components/ui/breadcrumb.tsx`:
- Around line 67-75: Breadcrumb components (e.g., BreadcrumbPage,
BreadcrumbSeparator, BreadcrumbEllipsis) currently forward {...props} after
fixed accessibility attributes which allows callers to override aria-current,
aria-disabled, role, and tabIndex; change the spreads so the forwarded props
cannot override those invariants by either spreading props first and then
explicitly setting aria-current, aria-disabled, role, and tabIndex (ensuring
fixed values win) or by omitting those keys from the forwarded props before
spreading (filter out "aria-current", "aria-disabled", "role", "tabIndex", and
any separator/ellipsis-related ARIA attributes), and keep the explicit
attributes (aria-current="page", aria-disabled="true", role="link" or
appropriate role, tabIndex={-1}) in BreadcrumbPage, BreadcrumbSeparator, and
BreadcrumbEllipsis to preserve accessibility semantics.
In `@src/components/ui/button-group.tsx`:
- Around line 31-37: The ButtonGroup JSX currently spreads {...props} after
fixed attributes so consumers can override role and data-* values; either move
{...props} before the fixed attributes (so role="group", data-orientation and
data-slot always win), or explicitly strip those keys from props before
spreading (e.g. extract role and any data-* props from the incoming props and
spread the remaining rest) in the ButtonGroup component where
buttonGroupVariants, className and props are used.
In `@src/components/ui/calendar.tsx`:
- Around line 206-233: The local ref created with useRef (ref) is never passed
into the rendered Button so ref.current?.focus() cannot focus the real element;
attach the ref to the Button by forwarding it into the component (pass ref={ref}
into <Button />) and ensure Button supports forwarded refs (if Button is a
custom component, update its implementation to accept and forward the ref to the
underlying button element using React.forwardRef); keep the existing
modifiers.focused useEffect logic as-is so focus handoff works.
In `@src/components/ui/carousel.tsx`:
- Around line 97-108: The effect registers both api.on("reInit", onSelect) and
api.on("select", onSelect) but only removes "select" in cleanup, leaving the
"reInit" listener dangling; update the React.useEffect cleanup to unsubscribe
both events (call api.off("reInit", onSelect) and api.off("select", onSelect))
and keep the initial onSelect(api) call and dependency array unchanged so
reInit/select listeners are properly removed on unmount or api swap.
- Around line 77-88: The keyboard handler handleKeyDown only handles
ArrowLeft/ArrowRight so vertical carousels (orientation === "vertical") lack
keyboard navigation; update handleKeyDown to branch on the component's
orientation prop (e.g., check orientation === "vertical") and, when vertical,
listen for "ArrowUp"/"ArrowDown" (calling scrollPrev()/scrollNext() and
event.preventDefault()), otherwise keep the existing "ArrowLeft"/"ArrowRight"
behavior; ensure the dependency array still includes scrollPrev and scrollNext
(and orientation if needed).
In `@src/components/ui/chart.tsx`:
- Around line 93-113: The current ChartStyle return builds raw HTML with
dangerouslySetInnerHTML using id, colorConfig keys and colors (and THEMES),
which can lead to CSS/HTML injection; replace this by not generating raw <style>
markup: either validate and whitelist id/series keys/colors before any
interpolation, or — preferred — stop using dangerouslySetInnerHTML in the
ChartStyle component and instead apply the theme variables directly to the chart
DOM node via safe React props/CSSOM (e.g., set CSS custom properties on the
element with data-chart={id} or update a stylesheet using document.styleSheets
API with properly escaped selectors), updating the logic that iterates THEMES
and colorConfig to assign only validated values to style properties rather than
embedding them in raw HTML.
In `@src/components/ui/context-menu.tsx`:
- Around line 150-159: ContextMenuSubContent currently passes {...props} after a
hardcoded className="shadow-lg", allowing a caller-supplied className in props
to overwrite the built-in elevation; update ContextMenuSubContent to merge the
incoming props.className with "shadow-lg" (using the project's class merging
utility or a simple join) and pass that merged value as the className to
ContextMenuContent instead of spreading props.last, preserving other props by
still spreading {...props} but without letting props.className override the
default.
In `@src/components/ui/field.tsx`:
- Line 196: Replace the loose equality check in the conditional that inspects
uniqueErrors?.length (the line with "if (uniqueErrors?.length == 1)") with a
strict equality operator, i.e. use "===" instead of "==", so the statement
becomes "if (uniqueErrors?.length === 1)"; update the same occurrence wherever
that exact conditional appears in the Field component or related function to
avoid type-coercion issues.
In `@src/components/ui/input-group.tsx`:
- Around line 53-58: The click handler in the InputGroup component only searches
for "input" elements so textarea-backed groups (InputGroupTextarea) won’t
receive focus; update the handler used in the onClick callback (the anonymous
function at the onClick where it does parentElement?.querySelector("input")) to
query for both inputs and textareas (e.g., "input, textarea") or otherwise
locate/input-or-textarea elements and call .focus() on the found element; apply
the same change to the other identical handler further down (the block around
lines 132-145) so addon clicks forward focus to InputGroupTextarea as well.
In `@src/components/ui/navigation-menu.tsx`:
- Around line 86-89: The Tailwind data-attribute value variants inside the
NavigationMenuPrimitive.Content className are using unsupported syntax
(data-ending-style:data-activation-direction=left/right and
data-starting-style:...), so update them to the bracketed value syntax used
elsewhere (e.g. data-[activation-direction=left]). In the className on
NavigationMenuPrimitive.Content replace each occurrence like
data-ending-style:data-activation-direction=left:translate-x-[50%],
data-ending-style:data-activation-direction=right:translate-x-[-50%],
data-starting-style:data-activation-direction=left:translate-x-[-50%], and
data-starting-style:data-activation-direction=right:translate-x-[50%] with
data-ending-style:data-[activation-direction=left]:translate-x-[50%],
data-ending-style:data-[activation-direction=right]:translate-x-[-50%],
data-starting-style:data-[activation-direction=left]:translate-x-[-50%], and
data-starting-style:data-[activation-direction=right]:translate-x-[50%]
respectively so Tailwind will generate the correct classes.
In `@src/components/ui/pagination.tsx`:
- Around line 109-119: The outer pagination ellipsis container currently has
aria-hidden which also hides the nested "More pages" sr-only label; remove
aria-hidden from the outer <span> (the element with
data-slot="pagination-ellipsis" and className) and instead mark the decorative
icon as hidden from AT (e.g., add aria-hidden={true} or role="img" with
aria-hidden on the IconDots SVG or wrapper) so the visible sr-only <span> "More
pages" remains reachable to screen readers while the icon stays ignored.
In `@src/components/ui/sidebar.tsx`:
- Around line 635-636: SidebarMenuSkeleton uses render-time randomness when
initializing const [width] = useState(() => `${Math.floor(Math.random() * 40) +
50}%`), which can cause SSR/CSR hydration mismatches; change this to a
deterministic width (e.g., fixed percentage or computed from props) or defer
randomness until after mount by initializing width to a stable value and setting
a random value inside a useEffect that runs only on the client (update the state
setter used in SidebarMenuSkeleton accordingly).
- Around line 82-89: Guard access to the Cookie Store API (cookieStore /
window.cookieStore) before calling cookieStore.set in the toggle/path that
writes the sidebar state, and when setting expiry use the correct field/type:
either pass maxAge: SIDEBAR_COOKIE_MAX_AGE (seconds) or compute expires:
Date.now() + SIDEBAR_COOKIE_MAX_AGE * 1000 (milliseconds) instead of passing the
seconds value directly; update references around SIDEBAR_COOKIE_NAME and
SIDEBAR_COOKIE_MAX_AGE where cookieStore.set is called. For SidebarMenuSkeleton,
remove Math.random() usage for inline --skeleton-width to avoid SSR hydration
mismatch—make widths deterministic (e.g., derive from a stable prop like index
or a preset sequence) or render the skeleton only on the client (client-only
wrapper) so server and client markup match. Ensure these changes touch
cookieStore usage and the SidebarMenuSkeleton component.
In `@src/components/ui/spinner.tsx`:
- Line 4: The files use React.ComponentProps/ComponentPropsWithRef in type
annotations but do not import the React types, causing type-check failures when
allowUmdGlobalAccess is off; add a type-only import such as import type * as
React from "react"; (or import type { ComponentProps, ComponentPropsWithRef }
from "react") at the top of src/components/ui/spinner.tsx and the other affected
files (refer to the Spinner function signature using React.ComponentProps<"svg">
and any usages of React.ComponentPropsWithRef in dropdown-menu and
navigation-menu) so the React namespace/types are available to the TypeScript
compiler.
In `@src/components/ui/toggle-group.tsx`:
- Around line 34-45: The CSS selectors in the ToggleGroup components don't match
the rendered attribute: you render data-orientation on ToggleGroupPrimitive but
the classes use data-vertical / group-data-vertical / group-data-horizontal, so
orientation-specific rules never apply; update the className strings in
ToggleGroup (where ToggleGroupPrimitive is used) and ToggleGroupItem to target
the actual attribute (e.g., use [data-orientation="vertical"] /
[data-orientation="horizontal"] or group/[data-orientation="vertical"] etc.)
instead of data-vertical/data-horizontal so the vertical/horizontal flex,
border, and rounding rules are applied correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e58b5fba-0ef3-4f34-93a5-dea765a431c6
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (76)
.cta.json.lintstagedrc.jsoncomponents.jsonpackage.jsonprisma.config.tssrc/components/form/form-checkbox.tsxsrc/components/sidebar/app-sidebar.tsxsrc/components/sidebar/nav-main.tsxsrc/components/sidebar/nav-secondary.tsxsrc/components/sidebar/nav-user.tsxsrc/components/sidebar/user-avatar.tsxsrc/components/ui/accordion.tsxsrc/components/ui/alert-dialog.tsxsrc/components/ui/alert.tsxsrc/components/ui/aspect-ratio.tsxsrc/components/ui/avatar.tsxsrc/components/ui/badge.tsxsrc/components/ui/breadcrumb.tsxsrc/components/ui/button-group.tsxsrc/components/ui/button.tsxsrc/components/ui/calendar.tsxsrc/components/ui/card.tsxsrc/components/ui/carousel.tsxsrc/components/ui/chart.tsxsrc/components/ui/checkbox.tsxsrc/components/ui/collapsible.tsxsrc/components/ui/combobox.tsxsrc/components/ui/command.tsxsrc/components/ui/context-menu.tsxsrc/components/ui/dialog.tsxsrc/components/ui/direction.tsxsrc/components/ui/drawer.tsxsrc/components/ui/dropdown-menu.tsxsrc/components/ui/empty.tsxsrc/components/ui/field.tsxsrc/components/ui/hover-card.tsxsrc/components/ui/input-group.tsxsrc/components/ui/input-otp.tsxsrc/components/ui/input.tsxsrc/components/ui/item.tsxsrc/components/ui/kbd.tsxsrc/components/ui/label.tsxsrc/components/ui/menubar.tsxsrc/components/ui/native-select.tsxsrc/components/ui/navigation-menu.tsxsrc/components/ui/pagination.tsxsrc/components/ui/popover.tsxsrc/components/ui/progress.tsxsrc/components/ui/radio-group.tsxsrc/components/ui/resizable.tsxsrc/components/ui/scroll-area.tsxsrc/components/ui/select.tsxsrc/components/ui/separator.tsxsrc/components/ui/sheet.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/skeleton.tsxsrc/components/ui/slider.tsxsrc/components/ui/spinner.tsxsrc/components/ui/switch.tsxsrc/components/ui/table.tsxsrc/components/ui/tabs.tsxsrc/components/ui/textarea.tsxsrc/components/ui/toggle-group.tsxsrc/components/ui/toggle.tsxsrc/components/ui/tooltip.tsxsrc/features/auth/components/sign-up-form.tsxsrc/features/auth/schema/index.tssrc/hooks/use-mobile.tssrc/integrations/root-provider.tsxsrc/lib/db.tssrc/lib/utils.tssrc/middleware.tssrc/routes/__root.tsxsrc/routes/api/auth/$.tssrc/styles.cssvite.config.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity in TypeScript
Preferunknownoveranywhen the type is genuinely unknown in TypeScript
Use const assertions (as const) for immutable values and literal types in TypeScript
Leverage TypeScript's type narrowing instead of type assertions
Files:
src/components/ui/direction.tsxsrc/components/ui/collapsible.tsxsrc/features/auth/schema/index.tssrc/integrations/root-provider.tsxsrc/components/sidebar/user-avatar.tsxsrc/components/sidebar/nav-main.tsxsrc/components/ui/checkbox.tsxprisma.config.tssrc/components/ui/spinner.tsxsrc/components/sidebar/nav-secondary.tsxsrc/components/ui/aspect-ratio.tsxsrc/routes/__root.tsxsrc/components/ui/resizable.tsxsrc/components/ui/hover-card.tsxsrc/hooks/use-mobile.tssrc/components/ui/separator.tsxsrc/components/ui/kbd.tsxsrc/components/sidebar/app-sidebar.tsxsrc/routes/api/auth/$.tsvite.config.tssrc/components/ui/skeleton.tsxsrc/components/sidebar/nav-user.tsxsrc/components/ui/input-otp.tsxsrc/components/ui/popover.tsxsrc/features/auth/components/sign-up-form.tsxsrc/components/ui/toggle-group.tsxsrc/middleware.tssrc/components/ui/slider.tsxsrc/components/form/form-checkbox.tsxsrc/components/ui/label.tsxsrc/components/ui/scroll-area.tsxsrc/components/ui/dialog.tsxsrc/components/ui/accordion.tsxsrc/lib/db.tssrc/components/ui/tabs.tsxsrc/components/ui/toggle.tsxsrc/components/ui/avatar.tsxsrc/components/ui/button.tsxsrc/components/ui/progress.tsxsrc/components/ui/tooltip.tsxsrc/components/ui/card.tsxsrc/components/ui/breadcrumb.tsxsrc/components/ui/empty.tsxsrc/components/ui/badge.tsxsrc/components/ui/table.tsxsrc/lib/utils.tssrc/components/ui/alert.tsxsrc/components/ui/native-select.tsxsrc/components/ui/input.tsxsrc/components/ui/textarea.tsxsrc/components/ui/button-group.tsxsrc/components/ui/carousel.tsxsrc/components/ui/radio-group.tsxsrc/components/ui/pagination.tsxsrc/components/ui/item.tsxsrc/components/ui/input-group.tsxsrc/components/ui/drawer.tsxsrc/components/ui/command.tsxsrc/components/ui/switch.tsxsrc/components/ui/alert-dialog.tsxsrc/components/ui/context-menu.tsxsrc/components/ui/select.tsxsrc/components/ui/chart.tsxsrc/components/ui/menubar.tsxsrc/components/ui/navigation-menu.tsxsrc/components/ui/combobox.tsxsrc/components/ui/calendar.tsxsrc/components/ui/sheet.tsxsrc/components/ui/field.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/dropdown-menu.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions in JavaScript/TypeScript
Preferfor...ofloops over.forEach()and indexedforloops in JavaScript/TypeScript
Use optional chaining (?.) and nullish coalescing (??) for safer property access in JavaScript/TypeScript
Prefer template literals over string concatenation in JavaScript/TypeScript
Use destructuring for object and array assignments in JavaScript/TypeScript
Useconstby default,letonly when reassignment is needed, nevervarin JavaScript/TypeScript
Alwaysawaitpromises in async functions - don't forget to use the return value
Useasync/awaitsyntax instead of promise chains for better readability in JavaScript/TypeScript
Handle errors appropriately in async code with try-catch blocks in JavaScript/TypeScript
Don't use async functions as Promise executors in JavaScript/TypeScript
Removeconsole.log,debugger, andalertstatements from production code in JavaScript/TypeScript
ThrowErrorobjects with descriptive messages, not strings or other values in JavaScript/TypeScript
Usetry-catchblocks meaningfully - don't catch errors just to rethrow them in JavaScript/TypeScript
Prefer early returns over nested conditionals for error cases in JavaScript/TypeScript
Extract complex conditions into well-named boolean variables in JavaScript/TypeScript
Use early returns to reduce nesting in JavaScript/TypeScript
Prefer simple conditionals over nested ternary operators in JavaScript/TypeScript
Group related code together and separate concerns in JavaScript/TypeScript
Don't useeval()or assign directly todocument.cookiein JavaScript/TypeScript
Validate and sanitize user input in JavaScript/TypeScript
Avoid spread syntax in accumulators within loops in JavaScript/TypeScript
Use top-level regex literals instead of creating them in loops in JavaScript/TypeScript
...
Files:
src/components/ui/direction.tsxsrc/components/ui/collapsible.tsxsrc/features/auth/schema/index.tssrc/integrations/root-provider.tsxsrc/components/sidebar/user-avatar.tsxsrc/components/sidebar/nav-main.tsxsrc/components/ui/checkbox.tsxprisma.config.tssrc/components/ui/spinner.tsxsrc/components/sidebar/nav-secondary.tsxsrc/components/ui/aspect-ratio.tsxsrc/routes/__root.tsxsrc/components/ui/resizable.tsxsrc/components/ui/hover-card.tsxsrc/hooks/use-mobile.tssrc/components/ui/separator.tsxsrc/components/ui/kbd.tsxsrc/components/sidebar/app-sidebar.tsxsrc/routes/api/auth/$.tsvite.config.tssrc/components/ui/skeleton.tsxsrc/components/sidebar/nav-user.tsxsrc/components/ui/input-otp.tsxsrc/components/ui/popover.tsxsrc/features/auth/components/sign-up-form.tsxsrc/components/ui/toggle-group.tsxsrc/middleware.tssrc/components/ui/slider.tsxsrc/components/form/form-checkbox.tsxsrc/components/ui/label.tsxsrc/components/ui/scroll-area.tsxsrc/components/ui/dialog.tsxsrc/components/ui/accordion.tsxsrc/lib/db.tssrc/components/ui/tabs.tsxsrc/components/ui/toggle.tsxsrc/components/ui/avatar.tsxsrc/components/ui/button.tsxsrc/components/ui/progress.tsxsrc/components/ui/tooltip.tsxsrc/components/ui/card.tsxsrc/components/ui/breadcrumb.tsxsrc/components/ui/empty.tsxsrc/components/ui/badge.tsxsrc/components/ui/table.tsxsrc/lib/utils.tssrc/components/ui/alert.tsxsrc/components/ui/native-select.tsxsrc/components/ui/input.tsxsrc/components/ui/textarea.tsxsrc/components/ui/button-group.tsxsrc/components/ui/carousel.tsxsrc/components/ui/radio-group.tsxsrc/components/ui/pagination.tsxsrc/components/ui/item.tsxsrc/components/ui/input-group.tsxsrc/components/ui/drawer.tsxsrc/components/ui/command.tsxsrc/components/ui/switch.tsxsrc/components/ui/alert-dialog.tsxsrc/components/ui/context-menu.tsxsrc/components/ui/select.tsxsrc/components/ui/chart.tsxsrc/components/ui/menubar.tsxsrc/components/ui/navigation-menu.tsxsrc/components/ui/combobox.tsxsrc/components/ui/calendar.tsxsrc/components/ui/sheet.tsxsrc/components/ui/field.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/dropdown-menu.tsx
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally in React
Specify all dependencies in hook dependency arrays correctly in React
Use thekeyprop for elements in iterables - prefer unique IDs over array indices in React
Nest children between opening and closing tags instead of passing as props in React
Don't define components inside other components in React
Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles in React
AvoiddangerouslySetInnerHTMLunless absolutely necessary in React
Use proper image components (e.g., Next.js<Image>) over<img>tags in Next.js
Use Next.js<Image>component for images in Next.js
Usenext/heador App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead ofReact.forwardRefin React 19+
Files:
src/components/ui/direction.tsxsrc/components/ui/collapsible.tsxsrc/integrations/root-provider.tsxsrc/components/sidebar/user-avatar.tsxsrc/components/sidebar/nav-main.tsxsrc/components/ui/checkbox.tsxsrc/components/ui/spinner.tsxsrc/components/sidebar/nav-secondary.tsxsrc/components/ui/aspect-ratio.tsxsrc/routes/__root.tsxsrc/components/ui/resizable.tsxsrc/components/ui/hover-card.tsxsrc/components/ui/separator.tsxsrc/components/ui/kbd.tsxsrc/components/sidebar/app-sidebar.tsxsrc/components/ui/skeleton.tsxsrc/components/sidebar/nav-user.tsxsrc/components/ui/input-otp.tsxsrc/components/ui/popover.tsxsrc/features/auth/components/sign-up-form.tsxsrc/components/ui/toggle-group.tsxsrc/components/ui/slider.tsxsrc/components/form/form-checkbox.tsxsrc/components/ui/label.tsxsrc/components/ui/scroll-area.tsxsrc/components/ui/dialog.tsxsrc/components/ui/accordion.tsxsrc/components/ui/tabs.tsxsrc/components/ui/toggle.tsxsrc/components/ui/avatar.tsxsrc/components/ui/button.tsxsrc/components/ui/progress.tsxsrc/components/ui/tooltip.tsxsrc/components/ui/card.tsxsrc/components/ui/breadcrumb.tsxsrc/components/ui/empty.tsxsrc/components/ui/badge.tsxsrc/components/ui/table.tsxsrc/components/ui/alert.tsxsrc/components/ui/native-select.tsxsrc/components/ui/input.tsxsrc/components/ui/textarea.tsxsrc/components/ui/button-group.tsxsrc/components/ui/carousel.tsxsrc/components/ui/radio-group.tsxsrc/components/ui/pagination.tsxsrc/components/ui/item.tsxsrc/components/ui/input-group.tsxsrc/components/ui/drawer.tsxsrc/components/ui/command.tsxsrc/components/ui/switch.tsxsrc/components/ui/alert-dialog.tsxsrc/components/ui/context-menu.tsxsrc/components/ui/select.tsxsrc/components/ui/chart.tsxsrc/components/ui/menubar.tsxsrc/components/ui/navigation-menu.tsxsrc/components/ui/combobox.tsxsrc/components/ui/calendar.tsxsrc/components/ui/sheet.tsxsrc/components/ui/field.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/dropdown-menu.tsx
**/*.{jsx,tsx,html}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx,html}: Addrel="noopener"when usingtarget="_blank"on links in React/HTML
Consider accessibility, performance, and usability for user experience in React/HTML
Files:
src/components/ui/direction.tsxsrc/components/ui/collapsible.tsxsrc/integrations/root-provider.tsxsrc/components/sidebar/user-avatar.tsxsrc/components/sidebar/nav-main.tsxsrc/components/ui/checkbox.tsxsrc/components/ui/spinner.tsxsrc/components/sidebar/nav-secondary.tsxsrc/components/ui/aspect-ratio.tsxsrc/routes/__root.tsxsrc/components/ui/resizable.tsxsrc/components/ui/hover-card.tsxsrc/components/ui/separator.tsxsrc/components/ui/kbd.tsxsrc/components/sidebar/app-sidebar.tsxsrc/components/ui/skeleton.tsxsrc/components/sidebar/nav-user.tsxsrc/components/ui/input-otp.tsxsrc/components/ui/popover.tsxsrc/features/auth/components/sign-up-form.tsxsrc/components/ui/toggle-group.tsxsrc/components/ui/slider.tsxsrc/components/form/form-checkbox.tsxsrc/components/ui/label.tsxsrc/components/ui/scroll-area.tsxsrc/components/ui/dialog.tsxsrc/components/ui/accordion.tsxsrc/components/ui/tabs.tsxsrc/components/ui/toggle.tsxsrc/components/ui/avatar.tsxsrc/components/ui/button.tsxsrc/components/ui/progress.tsxsrc/components/ui/tooltip.tsxsrc/components/ui/card.tsxsrc/components/ui/breadcrumb.tsxsrc/components/ui/empty.tsxsrc/components/ui/badge.tsxsrc/components/ui/table.tsxsrc/components/ui/alert.tsxsrc/components/ui/native-select.tsxsrc/components/ui/input.tsxsrc/components/ui/textarea.tsxsrc/components/ui/button-group.tsxsrc/components/ui/carousel.tsxsrc/components/ui/radio-group.tsxsrc/components/ui/pagination.tsxsrc/components/ui/item.tsxsrc/components/ui/input-group.tsxsrc/components/ui/drawer.tsxsrc/components/ui/command.tsxsrc/components/ui/switch.tsxsrc/components/ui/alert-dialog.tsxsrc/components/ui/context-menu.tsxsrc/components/ui/select.tsxsrc/components/ui/chart.tsxsrc/components/ui/menubar.tsxsrc/components/ui/navigation-menu.tsxsrc/components/ui/combobox.tsxsrc/components/ui/calendar.tsxsrc/components/ui/sheet.tsxsrc/components/ui/field.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/dropdown-menu.tsx
**/*.{jsx,tsx,vue,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
Use
classandforattributes instead ofclassNameandhtmlForin Solid/Svelte/Vue/Qwik
Files:
src/components/ui/direction.tsxsrc/components/ui/collapsible.tsxsrc/integrations/root-provider.tsxsrc/components/sidebar/user-avatar.tsxsrc/components/sidebar/nav-main.tsxsrc/components/ui/checkbox.tsxsrc/components/ui/spinner.tsxsrc/components/sidebar/nav-secondary.tsxsrc/components/ui/aspect-ratio.tsxsrc/routes/__root.tsxsrc/components/ui/resizable.tsxsrc/components/ui/hover-card.tsxsrc/components/ui/separator.tsxsrc/components/ui/kbd.tsxsrc/components/sidebar/app-sidebar.tsxsrc/components/ui/skeleton.tsxsrc/components/sidebar/nav-user.tsxsrc/components/ui/input-otp.tsxsrc/components/ui/popover.tsxsrc/features/auth/components/sign-up-form.tsxsrc/components/ui/toggle-group.tsxsrc/components/ui/slider.tsxsrc/components/form/form-checkbox.tsxsrc/components/ui/label.tsxsrc/components/ui/scroll-area.tsxsrc/components/ui/dialog.tsxsrc/components/ui/accordion.tsxsrc/components/ui/tabs.tsxsrc/components/ui/toggle.tsxsrc/components/ui/avatar.tsxsrc/components/ui/button.tsxsrc/components/ui/progress.tsxsrc/components/ui/tooltip.tsxsrc/components/ui/card.tsxsrc/components/ui/breadcrumb.tsxsrc/components/ui/empty.tsxsrc/components/ui/badge.tsxsrc/components/ui/table.tsxsrc/components/ui/alert.tsxsrc/components/ui/native-select.tsxsrc/components/ui/input.tsxsrc/components/ui/textarea.tsxsrc/components/ui/button-group.tsxsrc/components/ui/carousel.tsxsrc/components/ui/radio-group.tsxsrc/components/ui/pagination.tsxsrc/components/ui/item.tsxsrc/components/ui/input-group.tsxsrc/components/ui/drawer.tsxsrc/components/ui/command.tsxsrc/components/ui/switch.tsxsrc/components/ui/alert-dialog.tsxsrc/components/ui/context-menu.tsxsrc/components/ui/select.tsxsrc/components/ui/chart.tsxsrc/components/ui/menubar.tsxsrc/components/ui/navigation-menu.tsxsrc/components/ui/combobox.tsxsrc/components/ui/calendar.tsxsrc/components/ui/sheet.tsxsrc/components/ui/field.tsxsrc/components/ui/sidebar.tsxsrc/components/ui/dropdown-menu.tsx
**/index.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid barrel files (index files that re-export everything) in JavaScript/TypeScript
Files:
src/features/auth/schema/index.ts
🪛 ast-grep (0.43.0)
src/components/ui/chart.tsx
[warning] 94-94: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation
(react-unsafe-html-injection)
🪛 OpenGrep (1.22.0)
src/components/ui/chart.tsx
[WARNING] 93-114: dangerouslySetInnerHTML with dynamic content can lead to XSS. Sanitize the input with a library like DOMPurify before rendering.
(coderabbit.xss.react-dangerously-set-innerhtml)
🔇 Additional comments (37)
.cta.json (1)
28-28: LGTM!.lintstagedrc.json (1)
2-2: LGTM!components.json (1)
22-23: LGTM!prisma.config.ts (1)
4-11: LGTM!src/lib/db.ts (1)
6-6: LGTM!Also applies to: 10-10, 16-16
src/lib/utils.ts (1)
24-24: LGTM!src/styles.css (1)
9-48: LGTM!Also applies to: 52-83, 87-117, 121-134
vite.config.ts (1)
9-16: LGTM!src/hooks/use-mobile.ts (1)
6-21: LGTM!src/integrations/root-provider.tsx (1)
3-9: LGTM!src/features/auth/schema/index.ts (1)
6-25: LGTM!src/components/sidebar/nav-main.tsx (1)
6-8: LGTM!src/middleware.ts (1)
6-13: Auth redirect already preserves destination; src/middleware.ts authMiddleware isn’t currently wired
/ _app’sbeforeLoadredirects unauthenticated users to/sign-inwithsearch: { redirect: location.pathname }, and the sign-in/sign-up forms usesearch.redirectfor the post-auth navigation.
src/middleware.tsstill redirects to/sign-inwithoutsearch.redirect, butauthMiddlewareisn’t connected via TanStack Start config here (nocreateStart/requestMiddleware, nosrc/start.ts), so it shouldn’t affect the current flow unless wired later.> Likely an incorrect or invalid review comment.src/components/form/form-checkbox.tsx (1)
9-23: LGTM!src/components/ui/direction.tsx (1)
1-6: LGTM!src/components/ui/field.tsx (1)
1-52: LGTM!Also applies to: 53-85, 86-143, 144-173, 174-182, 210-237
src/components/ui/label.tsx (1)
1-20: LGTM!src/components/ui/radio-group.tsx (1)
1-36: LGTM!src/components/ui/skeleton.tsx (1)
1-13: LGTM!src/components/ui/collapsible.tsx (1)
1-27: LGTM!src/components/ui/checkbox.tsx (1)
1-27: LGTM!src/components/ui/button.tsx (1)
43-54: LGTM!src/components/ui/progress.tsx (1)
7-24: LGTM!Also applies to: 28-73
src/components/ui/sheet.tsx (1)
38-76: LGTM!src/components/ui/switch.tsx (1)
5-26: LGTM!src/components/ui/drawer.tsx (1)
1-5: Check client boundary safety forvaulDrawer wrapperSearches across
srcdidn’t find any direct import specifiers referencingsrc/components/ui/drawer.tsx(or paths containingdrawer) from otherts/tsxfiles, so there are no obvious server-side importers by path. However, if this wrapper is pulled in indirectly via barrel/re-export files, the importers may not mention thedrawerpath—so keep every consumer behind a client boundary (or restore"use client"in this file).src/components/ui/badge.tsx (1)
7-50: LGTM!src/components/ui/empty.tsx (1)
5-107: LGTM!src/components/ui/item.tsx (1)
8-199: LGTM!src/components/ui/separator.tsx (1)
1-25: LGTM!src/components/ui/tabs.tsx (1)
6-80: LGTM!src/components/ui/scroll-area.tsx (1)
1-52: LGTM!src/components/ui/slider.tsx (1)
5-55: LGTM!src/components/ui/input-group.tsx (1)
1-7: Add"use client"tosrc/components/ui/input-group.tsxif this module is used from React Server Components.
InputGroupAddondefines an inlineonClickhandler (around line 53) but the module header has no"use client"directive (lines 1-7), which is required for client-side event handlers in an RSC setup.Suggested fix
+"use client"; + import { cva, type VariantProps } from "class-variance-authority"; import type * as React from "react"; import { Button } from "`#/components/ui/button.tsx`"; import { Input } from "`#/components/ui/input.tsx`"; import { Textarea } from "`#/components/ui/textarea.tsx`"; import { cn } from "`#/lib/utils.ts`";src/components/ui/toggle.tsx (1)
8-45: LGTM!src/components/ui/input-otp.tsx (1)
6-84: LGTM!src/components/ui/resizable.tsx (1)
5-48: LGTM!
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
No description provided.