Skip to content

Docs Revamp - Apr 2026#1743

Merged
kotAPI merged 7 commits into
mainfrom
kotapi/docs-improvements-4-apr-2026
Apr 7, 2026
Merged

Docs Revamp - Apr 2026#1743
kotAPI merged 7 commits into
mainfrom
kotapi/docs-improvements-4-apr-2026

Conversation

@kotAPI

@kotAPI kotAPI commented Apr 5, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • "On this page" sticky table of contents with active-section highlighting
    • New floating demo surfaces and many interactive playground demos added
  • Documentation

    • Expanded local development guide with step-by-step run/build/link workflows
    • Consolidated API reference rendering across docs and added a page factory to standardize pages
    • Numerous component API docs and examples expanded
  • Style

    • Switched docs fonts to Manrope + JetBrains Mono; improved code block behavior and copy button styling
  • UX

    • Nav adapts on docs pages and shares dark-mode state for consistent controls

@changeset-bot

changeset-bot Bot commented Apr 5, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 3e3d95c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5aea24fa-389d-4e01-8240-1da3e2f6e6fc

📥 Commits

Reviewing files that changed from the base of the PR and between e825180 and 3e3d95c.

📒 Files selected for processing (48)
  • docs/app/globals.scss
  • docs/app/landingComponents/MusicAppPlayerDemo.js
  • docs/app/layout.js
  • docs/app/page.tsx
  • docs/app/playground/components/AccordionPlayground.js
  • docs/app/playground/components/AlertDialogPlayground.js
  • docs/app/playground/components/AspectRatioPlayground.js
  • docs/app/playground/components/AvatarGroupPlayground.js
  • docs/app/playground/components/CalloutPlayground.js
  • docs/app/playground/components/CardPlayground.js
  • docs/app/playground/components/DialogPlayground.js
  • docs/app/playground/components/KbdPlayground.js
  • docs/app/playground/components/ProgressPlayground.js
  • docs/app/playground/components/SeparatorPlayground.js
  • docs/app/playground/components/StrongPlayground.js
  • docs/app/playground/components/SwitchPlayground.js
  • docs/app/playground/components/TablePlayground.js
  • docs/app/playground/components/TabsPlayground.js
  • docs/app/playground/components/ToggleGroupPlayground.js
  • docs/app/playground/components/TogglePlayground.js
  • docs/app/playground/components/TooltipPlayground.js
  • docs/app/playground/components/VisuallyHiddenPlayground.js
  • docs/app/playground/helpers/ColorLooper.js
  • docs/app/playground/page.tsx
  • docs/app/showcase-dashboard/page.js
  • docs/app/showcase/dashboard/page.js
  • docs/app/showcase/helpers/DashboardDemo.js
  • docs/app/showcase/helpers/InboxDemo.js
  • docs/app/showcase/helpers/MessagingDemo.js
  • docs/app/showcase/helpers/PreferencesDemo.js
  • docs/app/showcase/helpers/ProductPageDemo.js
  • docs/app/showcase/helpers/ShowcaseTabs.tsx
  • docs/app/showcase/inbox/page.js
  • docs/app/showcase/layout.js
  • docs/app/showcase/messaging/page.js
  • docs/app/showcase/music-app/helpers/MusicPlayer.tsx
  • docs/app/showcase/music-app/helpers/MusicSidebar.js
  • docs/app/showcase/music-app/helpers/sections/PlaylistHero.tsx
  • docs/app/showcase/music-app/helpers/sections/TopArtists.tsx
  • docs/app/showcase/music-app/page.js
  • docs/app/showcase/preferences/page.js
  • docs/app/showcase/product-page/page.js
  • docs/app/sponsors/components/SponsorCard.tsx
  • docs/components/Main/NavBar/helpers/NavRoot/index.tsx
  • docs/components/hero/FloatingSurface.tsx
  • docs/components/layout/Documentation/DocsTableOfContents.tsx
  • docs/components/layout/Documentation/helpers/CodeBlock.js
  • docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js

📝 Walkthrough

Walkthrough

Updates the docs site: adds local development instructions, introduces a docs page factory and a two-column layout with an in-page table-of-contents and viewport-aware scrolling utilities, swaps global fonts, replaces many inline SVGs with lucide-react icons, consolidates API tables into ApiReference, enhances CodeBlock/Copy/Docs UI, and simplifies PostHog init.

Changes

Cohort / File(s) Summary
Local dev docs
README.md, docs/README.md, docs/app/docs/contributing/setting-up-dev-environment/content.mdx
Adds “Local development” guidance and step-by-step workflows for running Storybook and the docs site; documents building and linking @radui/ui into the docs app.
Fonts & global styles
docs/app/layout.js, docs/app/globals.scss, styles/cssTokens/base.tokens.css
Replaces Inter with Manrope + JetBrains Mono, switches body font usage to CSS font vars, updates code/token styles, and adjusts several global CSS selectors/animations.
Docs layout & TOC
docs/app/docs/layout.tsx, docs/components/layout/Documentation/DocsTableOfContents.tsx, docs/components/layout/Documentation/utils.js
Reworks docs into an article + sticky TOC two-column grid; adds client-side TOC component, viewport-aware getDocsViewport/scrollToDocsAnchor utilities, and IntersectionObserver‑based active-heading tracking.
Page factory & metadata wiring
docs/components/docsPage/createDocsPage.tsx, many docs/**/page.tsx
Adds createDocsPage(Content) factory; updates numerous pages to export createDocsPage(Content) and re-export metadata from ./seo instead of local assignments.
Navigation / sidebar / context
docs/components/Main/..., docs/components/navigation/*, docs/components/Main/NavBar/helpers/NavRoot/index.tsx
Adds darkMode to NavBar context and provider; NavRoot detects /docs route to switch styling and button variants; increases sidebar width and restyles nav items/categories.
Docs components & shared styles
docs/components/layout/Documentation/Documentation.js, docs/components/layout/Documentation/shared.js, docs/components/layout/Documentation/helpers/DocsTable.js
Introduces shared section class constants, refactors Documentation markup to use shared classes, standardizes table/container styling and replaces local icons with lucide components.
CodeBlock, Copy, Hero, Tabs
docs/components/layout/Documentation/helpers/CodeBlock.js, docs/components/layout/Documentation/helpers/ComponentHero/*, docs/components/layout/Documentation/helpers/CodeTabs.js, docs/components/Copy.js, docs/mdx-components.tsx
Adds ResizeObserver/overflow detection, inline copy header, inline code handling, new collapsed height; refactors ComponentHero/CodeTabs layout; Copy accepts className/iconSize and uses lucide-react icons; MDX pre override maps language to CodeBlock.
Icons & examples
many docs/app/docs/**/examples/*, docs/app/playground/components/*, docs/components/layout/Documentation/helpers/ComponentFeatures.js
Replaces numerous inline SVGs with lucide-react icons across examples, playgrounds, callouts, and feature lists; removes many unused local SVG components.
PostHog / analytics
docs/components/PostHogProvider.tsx, docs/posthog.ts
Trims and validates PostHog key, requires non-placeholder key, simplifies init flow (no dev-only logging/try-catch), and initializes only when a valid key exists.
Docs package, types & tsconfig
docs/package.json, docs/types/custom.d.ts, docs/tsconfig.json
Renames docs package to @radui/docs, bumps @radui/ui dep and adds lucide-react; adds ToggleGroup module typings; updates TS target/incremental and include rules.
Landing, showcase & playgrounds
docs/app/page.tsx, docs/app/showcase/**, docs/app/landingComponents/*, docs/app/playground/components/*
Overhauls homepage/landing, adds many showcase/playground/demo components, introduces new demo layouts, and removes some motion/react animated wrappers in demos.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DocsTOC as DocsTableOfContents
  participant DocsViewport as DocsViewport/ScrollArea
  participant History as BrowserHistory

  User->>DocsTOC: click TOC link
  DocsTOC->>DocsViewport: locate target heading in `#docs-article`
  DocsTOC->>DocsViewport: compute scroll position & call scrollToDocsAnchor(id)
  DocsViewport->>DocsViewport: smooth scroll to computed position (viewport.scrollTo)
  DocsViewport->>History: pushState("#id")
  DocsTOC->>DocsTOC: IntersectionObserver updates activeId
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • GoldGroove06

Poem

🐰 I swapped fonts with a nimble hop,
A TOC sprang up — I couldn’t stop.
I linked the library, built with flair,
Icons now gleam in lucide hair.
Hooray — the docs now hop and pop! 🥕

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kotapi/docs-improvements-4-apr-2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (1)
docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js (1)

2-2: ⚠️ Potential issue | 🟡 Minor

Remove unused useEffect import.

The useEffect hook is imported but never used in this component.

Proposed fix
-import { useState, useEffect } from 'react'
+import { useState } from 'react'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js` at
line 2, The import statement in CodeTabs imports useEffect but it is unused;
update the import in ComponentHero/CodeTabs.js to remove useEffect and only
import the hooks actually used (e.g., change "import { useState, useEffect }
from 'react'" to import only useState) so there are no unused imports.
🧹 Nitpick comments (4)
docs/posthog.ts (1)

3-9: Centralize the placeholder key constant to avoid duplication.

The placeholder string "your_posthog_api_key_here" is duplicated here and in docs/components/PostHogProvider.tsx (line 11). As per coding guidelines, "If a custom person/event property is referenced in two or more places, define it in a central enum (TS) or const object (JS) and reuse that reference."

Consider extracting both the trimmed key and validation logic to a shared module:

♻️ Proposed refactor: Create a shared constants file

Create a new file docs/lib/posthog-constants.ts:

export const POSTHOG_PLACEHOLDER_KEY = "your_posthog_api_key_here" as const

export const postHogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY?.trim()

export const hasPostHogKey =
  typeof postHogKey === "string" &&
  postHogKey.length > 0 &&
  postHogKey !== POSTHOG_PLACEHOLDER_KEY

Then update this file:

 import { PostHog } from "posthog-node"
+import { postHogKey, hasPostHogKey } from "../lib/posthog-constants"

-const postHogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY?.trim()
-
 // NOTE: This is a Node.js client, so you can use it for sending events from the server side to PostHog.
 export default function PostHogClient() {
-  if (!postHogKey || postHogKey === "your_posthog_api_key_here") {
+  if (!hasPostHogKey) {
     return null
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/posthog.ts` around lines 3 - 9, Extract the placeholder string and
key-validation logic into a shared constants module (e.g., export
POSTHOG_PLACEHOLDER_KEY, postHogKey, and hasPostHogKey), then update the
PostHogClient function to import and use hasPostHogKey (or the imported
postHogKey/POSTHOG_PLACEHOLDER_KEY) instead of duplicating the literal
"your_posthog_api_key_here" and trimming logic; ensure PostHogClient returns
null when hasPostHogKey is false and remove the local duplication of postHogKey
and the placeholder string.
README.md (1)

90-97: Consider adding note about re-linking after rebuild.

The docs/README.md includes a helpful note: "If the docs app is already using the published package, re-run pnpm link @radui/ui`` after rebuilding the library." Adding this here would improve consistency and help contributors avoid confusion when their changes don't appear.

Suggested addition
 npm run build:rollup
 npm link
 cd docs
 pnpm link `@radui/ui`

+After rebuilding the library, re-run pnpm link @radui/ui`` in docs/ to pick up the changes.

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @README.md around lines 90 - 97, Add a short note after the linking
instructions reminding contributors to re-link the local package in the docs app
after rebuilding the library; specifically mention re-running the command "pnpm
link @radui/ui" inside the docs/ directory so the docs app picks up rebuilt
changes (mirror the guidance from docs/README.md).


</details>

</blockquote></details>
<details>
<summary>docs/app/docs/contributing/setting-up-dev-environment/content.mdx (1)</summary><blockquote>

`64-80`: **Consider adding re-link reminder for consistency.**

The `docs/README.md` includes a helpful note about re-running `pnpm link `@radui/ui`` after rebuilding the library when the docs app was previously using the published package. Adding this here would maintain consistency across all local development documentation.


<details>
<summary>Suggested addition</summary>

````diff
 ```bash
 pnpm link `@radui/ui`
 pnpm dev

+If the docs app was previously using the published package, re-run pnpm link @radui/ui`` after each rebuild.

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@docs/app/docs/contributing/setting-up-dev-environment/content.mdx` around
lines 64 - 80, Add a short re-link reminder to the "Testing local library
changes in the docs app" section: after the steps that show running `npm run
build:rollup` / `npm link` and `pnpm link `@radui/ui`` / `pnpm dev`, insert a
one-line note that if the docs app was previously consuming the published
package you must re-run `pnpm link `@radui/ui`` after each rebuild; reference the
existing commands (`npm run build:rollup`, `pnpm link `@radui/ui``, `pnpm dev`) so
the reviewer can place the note immediately after those commands for consistency
with docs/README.md.
```

</details>

</blockquote></details>
<details>
<summary>docs/components/navigation/NavItem.js (1)</summary><blockquote>

`22-22`: **Consider using Tailwind class instead of inline style.**

For consistency with the rest of the codebase, the inline `style={{fontSize:'10px'}}` could be replaced with a Tailwind class.


<details>
<summary>Proposed fix</summary>

```diff
-            {item.is_new?<div style={{fontSize:'10px'}}><Badge color="orange" customRootClass="rad-ui-docs" className="rounded-full bg-amber-100 text-amber-1000">New</Badge></div>:null}
+            {item.is_new?<div className="text-[10px]"><Badge color="orange" customRootClass="rad-ui-docs" className="rounded-full bg-amber-100 text-amber-1000">New</Badge></div>:null}
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@docs/components/navigation/NavItem.js` at line 22, Replace the inline style
on the conditional New badge in NavItem.js—currently rendered when
item.is_new—with an equivalent Tailwind utility class (e.g., text-[10px] or
text-xs with adjusted tracking) instead of style={{fontSize:'10px'}}; update the
JSX around item.is_new and the Badge component to use the Tailwind class on the
wrapping div or Badge root (refer to item.is_new and Badge) so styling is
consistent with the codebase.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

```
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/app/docs/layout.tsx`:
- Around line 87-91: The Tailwind important modifier is in the wrong order in
the Link className(s): change any occurrence of "!hover:underline" to
"hover:!underline" (e.g., the Link with className="!text-gray-1000
!hover:underline" and the Link with className="!text-gray-1000 !hover:underline
p-0") so the variant (hover) comes first, then the utility (underline), then the
important modifier.

In `@docs/app/layout.js`:
- Line 150: The body element in docs/app/layout.js currently uses className
"h-screen overflow-hidden font-sans" which forces Tailwind's default sans stack
and overrides globals.scss; either remove the font-sans token from that
className on the body element (keep "h-screen overflow-hidden") or update
docs/tailwind.config.ts to set theme.extend.fontFamily.sans to use
"var(--font-sans)" so the .font-sans utility resolves to your CSS variable and
allows Manrope from globals.scss to apply.

In `@docs/components/layout/Documentation/DocsTableOfContents.tsx`:
- Around line 86-94: The cleanup currently cancels the requestAnimationFrame
stored in frame but does not clear the delayed setTimeout that calls buildToc;
capture the timeout id when calling window.setTimeout (e.g., const timeout =
window.setTimeout(...)) alongside frame and then call
window.clearTimeout(timeout) in the returned cleanup function so the delayed
rebuild is canceled and no stale IntersectionObserver or activeId updates occur
after unmount/navigation; update any variable types if needed (timeout may be
number | undefined) and ensure observer?.disconnect() still runs.

In `@docs/components/layout/Documentation/utils.js`:
- Around line 7-29: scrollToDocsAnchor currently forces smooth animation; update
it to respect the user's reduced-motion preference by checking
window.matchMedia('(prefers-reduced-motion: reduce)').matches (or equivalent)
and choose behavior = 'auto' when reduced-motion is true, otherwise 'smooth';
apply this behavior value to both viewport.scrollTo (top/behavior) and
element.scrollIntoView (behavior/block) while leaving getDocsViewport, element
selection, computed top, and window.history.pushState unchanged.

In `@docs/components/navigation/Navigation.tsx`:
- Around line 48-53: The "Framework" block in Navigation.tsx is visually a
dropdown but has no interactivity; either implement dropdown state and handlers
or mark it non-interactive. To implement: add a useState hook (e.g.,
isFrameworkOpen) and a click handler on the container div that toggles it,
render the dropdown menu conditionally (and close on outside click/ESC), and add
accessible attributes (role="button", aria-expanded={isFrameworkOpen},
tabIndex=0) to the container that currently wraps the <span>Framework</span> and
the SVG chevron; alternatively, if you want it non-functional for now, remove
the chevron or change its styles and add aria-disabled or visually indicate
disabled so users don’t expect a dropdown. Ensure changes reference the
container div around "Framework", the <span>Framework</span>, and the chevron
SVG in Navigation.tsx.
- Around line 40-46: The Search button in Navigation.tsx is non-functional; add
a proper handler and keyboard binding: create a handleOpenSearch (or openSearch)
function in the Navigation component and wire it to the button's onClick to open
your search UI/modal (or set a searchOpen state), add accessible attributes
(aria-label/title) to the button, and register a useEffect that listens for the
"k" key (ignoring inputs and when modifier keys are pressed) to call
handleOpenSearch; if this is intentionally unimplemented, instead mark the
button disabled and add a clear TODO comment referencing handleOpenSearch or
openSearch so the placeholder is explicit.

In `@README.md`:
- Line 73: Replace the hardcoded absolute path in the README line that
references the documentation directory; update the text to use a relative path
or just the directory name (e.g., "use `pnpm` inside `docs/`") instead of
`/Users/pranaykothapalli/.../ui/docs` so the README is portable and not tied to
a local machine.

---

Outside diff comments:
In `@docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js`:
- Line 2: The import statement in CodeTabs imports useEffect but it is unused;
update the import in ComponentHero/CodeTabs.js to remove useEffect and only
import the hooks actually used (e.g., change "import { useState, useEffect }
from 'react'" to import only useState) so there are no unused imports.

---

Nitpick comments:
In `@docs/app/docs/contributing/setting-up-dev-environment/content.mdx`:
- Around line 64-80: Add a short re-link reminder to the "Testing local library
changes in the docs app" section: after the steps that show running `npm run
build:rollup` / `npm link` and `pnpm link `@radui/ui`` / `pnpm dev`, insert a
one-line note that if the docs app was previously consuming the published
package you must re-run `pnpm link `@radui/ui`` after each rebuild; reference the
existing commands (`npm run build:rollup`, `pnpm link `@radui/ui``, `pnpm dev`) so
the reviewer can place the note immediately after those commands for consistency
with docs/README.md.

In `@docs/components/navigation/NavItem.js`:
- Line 22: Replace the inline style on the conditional New badge in
NavItem.js—currently rendered when item.is_new—with an equivalent Tailwind
utility class (e.g., text-[10px] or text-xs with adjusted tracking) instead of
style={{fontSize:'10px'}}; update the JSX around item.is_new and the Badge
component to use the Tailwind class on the wrapping div or Badge root (refer to
item.is_new and Badge) so styling is consistent with the codebase.

In `@docs/posthog.ts`:
- Around line 3-9: Extract the placeholder string and key-validation logic into
a shared constants module (e.g., export POSTHOG_PLACEHOLDER_KEY, postHogKey, and
hasPostHogKey), then update the PostHogClient function to import and use
hasPostHogKey (or the imported postHogKey/POSTHOG_PLACEHOLDER_KEY) instead of
duplicating the literal "your_posthog_api_key_here" and trimming logic; ensure
PostHogClient returns null when hasPostHogKey is false and remove the local
duplication of postHogKey and the placeholder string.

In `@README.md`:
- Around line 90-97: Add a short note after the linking instructions reminding
contributors to re-link the local package in the docs app after rebuilding the
library; specifically mention re-running the command "pnpm link `@radui/ui`"
inside the docs/ directory so the docs app picks up rebuilt changes (mirror the
guidance from docs/README.md).
```

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `740124ed-134f-4dd0-8880-26af25076345`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 5b55d3ccc2c91fe38bf95c41aa8e1997e8a6ed21 and 927af35ed543ee5a5b24902416a0813411a7f2b7.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `docs/pnpm-lock.yaml` is excluded by `!**/pnpm-lock.yaml`

</details>

<details>
<summary>📒 Files selected for processing (23)</summary>

* `README.md`
* `docs/README.md`
* `docs/app/docs/contributing/setting-up-dev-environment/content.mdx`
* `docs/app/docs/layout.tsx`
* `docs/app/globals.scss`
* `docs/app/layout.js`
* `docs/components/Copy.js`
* `docs/components/Main/Main.js`
* `docs/components/Main/NavBar/NavBarContext.tsx`
* `docs/components/Main/NavBar/helpers/NavRoot/index.tsx`
* `docs/components/PostHogProvider.tsx`
* `docs/components/layout/Documentation/DocsTableOfContents.tsx`
* `docs/components/layout/Documentation/Documentation.js`
* `docs/components/layout/Documentation/helpers/CodeBlock.js`
* `docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js`
* `docs/components/layout/Documentation/helpers/ComponentHero/ComponentHero.js`
* `docs/components/layout/Documentation/helpers/DocsTable.js`
* `docs/components/layout/Documentation/utils.js`
* `docs/components/navigation/Category.tsx`
* `docs/components/navigation/NavItem.js`
* `docs/components/navigation/Navigation.tsx`
* `docs/package.json`
* `docs/posthog.ts`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread docs/app/docs/layout.tsx Outdated
Comment thread docs/app/layout.js Outdated
Comment thread docs/components/layout/Documentation/DocsTableOfContents.tsx
Comment thread docs/components/layout/Documentation/utils.js
Comment thread docs/components/navigation/Navigation.tsx Outdated
Comment thread docs/components/navigation/Navigation.tsx Outdated
Comment thread README.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 16

Caution

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

⚠️ Outside diff range comments (1)
docs/components/ui/Tooltip/index.tsx (1)

9-17: ⚠️ Potential issue | 🟡 Minor

Avoid rendering empty tooltip content when label is omitted.

Since label is optional now, rendering Tooltip.Content unconditionally can produce empty tooltips.

Proposed fix
-const TooltipWrapper = ({ children, label = '', placement = 'bottom', ...props }: TooltipWrapperProps) => {
+const TooltipWrapper = ({ children, label, placement = 'bottom', ...props }: TooltipWrapperProps) => {
@@
-            <Tooltip.Content>
-                {label}
-            </Tooltip.Content>
+            {label !== undefined && label !== null && label !== '' ? (
+                <Tooltip.Content>{label}</Tooltip.Content>
+            ) : null}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/components/ui/Tooltip/index.tsx` around lines 9 - 17, TooltipWrapper
currently always renders <Tooltip.Content> which can produce empty tooltips when
the optional label prop is omitted; update TooltipWrapper so that
Tooltip.Content is rendered only when label is non-empty (i.e., check truthiness
of the label prop before rendering Tooltip.Content). Locate the TooltipWrapper
component and replace the unconditional Tooltip.Content with a conditional
render (render Tooltip.Content with the label only when label is present) to
avoid empty tooltips. Ensure you preserve the existing placement prop and other
props passed into <Tooltip.Root> and keep the Trigger asChild behavior
unchanged.
🧹 Nitpick comments (18)
docs/app/showcase/music-app/helpers/MusicPlayer.tsx (2)

21-27: Avoid using any type; use proper TypeScript interfaces.

The component and its props are typed as any, which defeats TypeScript's type safety. Consider using a proper type for the children prop.

♻️ Proposed fix
-const IconContainerSmall: any = ({ children }: any) => {
+const IconContainerSmall: React.FC<{ children: React.ReactNode }> = ({ children }) => {
     return (
         <button className='flex h-11 w-11 items-center justify-center rounded-full border border-white/10 bg-white/5 text-white/70 transition hover:border-white/20 hover:bg-white/10 hover:text-white'>
             {children}
         </button>
     );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/showcase/music-app/helpers/MusicPlayer.tsx` around lines 21 - 27,
IconContainerSmall is typed with `any` which disables type safety; replace `any`
by defining a props interface like `interface IconContainerSmallProps {
children: React.ReactNode; }` and annotate the component signature to use that
interface and proper return type (e.g., `const IconContainerSmall:
React.FC<IconContainerSmallProps>` or `: JSX.Element`), ensuring you import
React types if needed and remove all `any` usages in that file.

33-38: Consider extracting the pause icon for better readability.

The inline ternary with nested JSX is dense. Extracting the pause icon into a small component or variable would improve readability, especially since a dedicated PauseIcon would mirror the existing PlayIcon import pattern.

♻️ Suggested refactor
+const PauseIcon: React.FC = () => (
+    <span className='flex gap-1.5'>
+        <span className='h-4 w-1 rounded-full bg-white' />
+        <span className='h-4 w-1 rounded-full bg-white' />
+    </span>
+);
+
 const PlayButton: React.FC = () => {
     const [isPlaying, setIsPlaying] = useState(false)

     return (
         <button
             onClick={() => setIsPlaying((value) => !value)}
             className='mx-2 flex h-14 w-14 items-center justify-center rounded-full bg-gradient-to-br from-orange-500 to-rose-400 text-white shadow-xl transition hover:scale-[1.03]'
         >
-            {isPlaying ? <span className='flex gap-1.5'><span className='h-4 w-1 rounded-full bg-white'/><span className='h-4 w-1 rounded-full bg-white'/></span> : <div className='ml-0.5 h-5 w-5'><PlayIcon /></div>}
+            {isPlaying ? <PauseIcon /> : <div className='ml-0.5 h-5 w-5'><PlayIcon /></div>}
         </button>
     );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/showcase/music-app/helpers/MusicPlayer.tsx` around lines 33 - 38,
Extract the inline pause markup into a reusable PauseIcon component (or const
PauseIcon = () => ...) and replace the nested JSX inside the ternary with
<PauseIcon /> to match the existing PlayIcon pattern; update the MusicPlayer
button JSX (the onClick uses setIsPlaying and the ternary checking isPlaying) to
render <PauseIcon /> when isPlaying is true and keep <PlayIcon /> when false,
ensuring you export/import PauseIcon similarly to PlayIcon and preserve existing
classes/spacing.
docs/components/layout/Documentation/helpers/ComponentFeatures/ComponentFeatures.js (1)

17-19: Prefer a stable key over array index

Line 18 uses key={index}. If features can ever reorder or change, this can cause subtle UI state mismatches; use a stable value key when possible.

Suggested tweak
-        {features.map((feature, index) => (
-          <li className="flex items-center space-x-2" key={index}>
+        {features.map((feature) => (
+          <li className="flex items-center space-x-2" key={feature}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@docs/components/layout/Documentation/helpers/ComponentFeatures/ComponentFeatures.js`
around lines 17 - 19, The list items use key={index} in the features.map
rendering which can cause UI state bugs when items reorder; update the <li> key
to use a stable unique identifier from the feature object (e.g., feature.id,
feature.key, or a unique feature.title/name) in the ComponentFeatures mapping
instead of the array index, and if no stable property exists add a unique id to
each feature when the data is created so the key remains consistent across
re-renders.
docs/app/showcase/music-app/helpers/MusicSidebar.js (1)

25-29: Add type="button" to prevent unintended form submissions.

Buttons default to type="submit" in HTML. If this component is ever rendered inside a <form>, clicking it would trigger form submission. Adding type="button" is a defensive best practice.

Suggested fix
-    return <button className={`flex w-full items-center justify-between rounded-2xl border px-3 py-3 text-left transition-all duration-300 ${
+    return <button type="button" className={`flex w-full items-center justify-between rounded-2xl border px-3 py-3 text-left transition-all duration-300 ${
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/showcase/music-app/helpers/MusicSidebar.js` around lines 25 - 29,
The returned button in MusicSidebar.js currently lacks an explicit type, so when
rendered inside a form it will act as a submit button; update the JSX for the
button element returned by the component (the <button ...> in the render/return
of MusicSidebar) to include type="button" to prevent unintended form submissions
while preserving the existing className and props.
docs/app/showcase/music-app/helpers/sections/PlaylistHero.tsx (1)

36-37: Consider adding explicit return types instead of any for components.

Components in this file use any for their type annotations (lines 36 and 62). While the docs directory runs with TypeScript's strict: false mode, explicitly typing return values as React.JSX.Element improves clarity at component boundaries and aligns with the stricter configuration of the main src directory.

Suggested improvement
-const InteractiveAlbums: any = () => {
+const InteractiveAlbums = (): React.JSX.Element => {
@@
-const PlaylistHero: any = () => {
+const PlaylistHero = (): React.JSX.Element => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/showcase/music-app/helpers/sections/PlaylistHero.tsx` around lines
36 - 37, Replace the loose `any` return/type annotations with explicit React
element types: change the component declaration for InteractiveAlbums to return
React.JSX.Element (e.g., `const InteractiveAlbums = (): React.JSX.Element =>
...`) and do the same for the other component(s) in this file that currently use
`any` (the declaration around line 62), ensuring component signatures use
React.JSX.Element instead of `any`.
docs/app/showcase/music-app/helpers/sections/TopArtists.tsx (1)

86-86: Add type definitions for Artist component and data arrays to improve type safety.

Line 86 uses any for both component and props, removing TypeScript safety for property access on artist.genre, artist.monthly, and artist.album (lines 90–102). Define concrete types for the data structures and component props:

♻️ Suggested typed refactor
+type ArtistData = {
+  name: string
+  album: string
+  image: string
+  genre: string
+  monthly: string
+}
+
+type QueueTrack = {
+  title: string
+  artist: string
+  length: string
+}
+
-const artistsData = [
+const artistsData: ArtistData[] = [
  // ...
]
 
-const quickQueue = [
+const quickQueue: QueueTrack[] = [
  // ...
]
 
-const Artist: any = ({ artist, index }: any) => {
+type ArtistProps = { artist: ArtistData; index: number }
+const Artist = ({ artist, index }: ArtistProps) => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/showcase/music-app/helpers/sections/TopArtists.tsx` at line 86, The
Artist component is typed as any which loses safety when accessing artist.genre,
artist.monthly, and artist.album; create explicit TypeScript types (e.g.,
interface ArtistData { id: string; name: string; genre: string; monthly: number;
album: string; image?: string } and type ArtistProps = { artist: ArtistData;
index: number }) and replace the any usages on the Artist component signature
and on the arrays that feed it (the top artists data array(s)) so the component
and data are strongly typed and property access is validated by the compiler.
docs/app/playground/components/HeadingPlayground.js (1)

9-9: Remove obsolete loop prop from ColorLooper usage.

Line 9 passes loop={false}, but ColorLooper no longer accepts or uses it. Removing stale props will keep the API surface clean.

♻️ Suggested cleanup
         <ColorLooper
-            loop={false}
             title="Heading"
             docsLink="/docs/components/heading"
             description="Type scale preview using the current heading component and semantic tags."
         >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/playground/components/HeadingPlayground.js` at line 9, Remove the
obsolete loop={false} prop from the ColorLooper usage in
HeadingPlayground.js—locate the JSX where ColorLooper is rendered (identifier:
ColorLooper) and delete the loop prop so the component call only includes props
that ColorLooper actually accepts.
docs/app/playground/page.tsx (1)

32-35: Keep the coverage summary in sync with rendered demos.

Line 33 currently lists a subset, but Line 40-49 renders additional playgrounds (blockquote, code, heading, em, link, text). This makes the header copy misleading.

Suggested copy update
-                                <span>Coverage: avatar, badge, button, typography, separator</span>
+                                <span>Coverage: avatar, badge, button, blockquote, code, heading, em, link, separator, text</span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/playground/page.tsx` around lines 32 - 35, Update the coverage
summary text inside the div with class 'grid gap-2 text-sm text-gray-700
md:max-w-xs' (the two span elements rendered in page.tsx) so it lists all demos
actually rendered below: include avatar, badge, button, typography, separator,
blockquote, code, heading, em, link and text; change the first span content from
the current subset to the full, accurate list and keep the second span about
focus unchanged.
docs/app/playground/components/SeparatorPlayground.js (1)

33-33: Avoid relative date wording in static docs copy.

Line 33 (Updated today) will become stale and ambiguous. Prefer a concrete month/year or a value sourced from metadata.

Simple copy tweak
-                    <Text><Em>Updated today</Em></Text>
+                    <Text><Em>Updated April 2026</Em></Text>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/playground/components/SeparatorPlayground.js` at line 33, Replace
the relative date string "Updated today" inside the SeparatorPlayground.js
component (the Text/Em element that currently renders that copy) with a concrete
date or derive it from page metadata; update the Text/Em node so it either
renders a fixed month/year (e.g., "Updated March 2026") or reads a timestamp
prop/metadata value (e.g., lastUpdated) and formats that, ensuring the displayed
text is not time-relative and will not become stale.
docs/app/docs/components/callout/examples/CalloutExample.tsx (1)

8-17: Inconsistent JSX indentation.

The <Callout.Root> opening tag and its children have extra indentation that doesn't align with the closing tag or the component definition pattern.

🧹 Suggested formatting fix
 const CalloutExample = () => (
-        <Callout.Root color="red">
-            <Callout.Icon>
-                <BookmarkIcon />
-            </Callout.Icon>
+    <Callout.Root color="red">
+        <Callout.Icon>
+            <BookmarkIcon />
+        </Callout.Icon>
         <Callout.Text>
             Seems like there's been an error. Please try again.
         </Callout.Text>
     </Callout.Root>
 )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/docs/components/callout/examples/CalloutExample.tsx` around lines 8
- 17, The JSX in CalloutExample (Callout.Root, Callout.Icon, Callout.Text) has
inconsistent indentation—align the opening <Callout.Root> tag, its child
elements (<Callout.Icon>, <Callout.Text>) and the closing </Callout.Root> with
the component declaration so the indentation level is consistent; update the
whitespace so children are indented one level inside Callout.Root and the
closing tag lines up with the component name to match the project formatting
pattern.
docs/app/docs/components/toggle-group/docs/component_api/item.tsx (1)

32-32: Consider using a more specific type than any for the value prop.

Using any weakens documentation clarity. If the underlying component accepts specific types, documenting them (e.g., string | number) would be more informative for consumers.

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

In `@docs/app/docs/components/toggle-group/docs/component_api/item.tsx` at line
32, The docs currently declare the prop type for value as the generic "any";
update the value prop to a specific type (e.g., string | number or string |
number | boolean) or, better, reference the actual component prop type (e.g.,
ToggleItemProps['value'] or ToggleGroupItemProps['value']) so consumers see the
real accepted types; change the type entry for value in the item component API
from "any" to the chosen union or the referenced prop type and run the
type-check/build to confirm the docs reflect the corrected type.
docs/app/docs/components/accordion/content.mdx (1)

5-8: Consider removing excessive blank lines.

Four consecutive blank lines here appear to be a cleanup artifact from removed code. Could be trimmed to a single blank line for consistency.

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

In `@docs/app/docs/components/accordion/content.mdx` around lines 5 - 8, Remove
the four consecutive blank lines in the Accordion content MDX file and collapse
them to a single blank line for consistency; open the "content.mdx" for the
accordion component (the MDX document that contains the accordion content) and
delete the extra empty lines so only one blank line remains between sections or
before the next block.
docs/app/docs/components/dialog/docs/component_api/root.tsx (1)

51-57: Avoid listing unsupported props as regular API rows.

defaultOpen is documented as “not supported” (Line 54) but still appears in the prop table, which can mislead consumers. Consider moving this to a “Not supported / differences from Radix” note section instead of a standard prop entry.

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

In `@docs/app/docs/components/dialog/docs/component_api/root.tsx` around lines 51
- 57, Remove the "defaultOpen" row from the standard prop table (the prop entry
where prop.name is "defaultOpen") and instead add a short "Not supported /
differences from Radix" note in the component's API docs explaining that
defaultOpen is not supported on this wrapper and how to control initial state
via external state; update any tooltip or type/default references for
"defaultOpen" so they only appear in that note section and not as a regular prop
entry.
docs/app/docs/components/toggle-group/docs/toggle-group-example-basic.tsx (1)

18-24: Consider using descriptive aria-label values for better accessibility.

Using item.value (e.g., "item1") as aria-label doesn't convey meaning to screen reader users. Consider using descriptive labels that match the icon's purpose:

 const items = [
-    { label: <Square size={15} strokeWidth={2} />, value: 'item1' },
-    { label: <Crop size={15} strokeWidth={2} />, value: 'item2' },
-    { label: <Layers3 size={15} strokeWidth={2} />, value: 'item3' },
-    { label: <Columns3 size={15} strokeWidth={2} />, value: 'item4' }
+    { label: <Square size={15} strokeWidth={2} />, value: 'item1', ariaLabel: 'Frame' },
+    { label: <Crop size={15} strokeWidth={2} />, value: 'item2', ariaLabel: 'Crop' },
+    { label: <Layers3 size={15} strokeWidth={2} />, value: 'item3', ariaLabel: 'Layers' },
+    { label: <Columns3 size={15} strokeWidth={2} />, value: 'item4', ariaLabel: 'Columns' }
 ];

Then use aria-label={item.ariaLabel} in the ToggleGroup.Item.

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

In `@docs/app/docs/components/toggle-group/docs/toggle-group-example-basic.tsx`
around lines 18 - 24, The aria-labels for ToggleGroup.Item are currently using
item.value (e.g., "item1") which is not descriptive; update the items data to
include a descriptive property (e.g., ariaLabel) and change the ToggleGroup.Item
prop to use aria-label={item.ariaLabel} so screen readers receive meaningful
labels; locate the items array and the ToggleGroup.Item usage in the example and
ensure each item has an ariaLabel string that describes the icon's purpose and
is referenced by ToggleGroup.Item.
docs/app/globals.scss (1)

62-65: Inconsistent selector: .function-variable missing code prefix.

The .function-variable selector lacks the code prefix that other syntax highlighting selectors have, which could cause unintended styling outside of code blocks.

Suggested fix
-code .function,
-.function-variable {
+code .function,
+code .function-variable {
   color: var(--rad-ui-color-blue-900);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/globals.scss` around lines 62 - 65, The .function-variable selector
is missing the code prefix and may apply styles outside code blocks; update the
selector list used for syntax highlighting to include the code-scoped selector
(i.e., change the rule that currently targets "code .function,
.function-variable" to target "code .function, code .function-variable" or
equivalent) so both .function and .function-variable are only styled inside code
elements; modify the rule where .function-variable is declared to use the
code-prefixed selector.
docs/app/docs/layout.tsx (1)

55-57: Dead code: DocsLayoutChunks is unused.

This component always returns null and the associated code (lines 98-99) is commented out. Consider removing it if no longer needed.

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

In `@docs/app/docs/layout.tsx` around lines 55 - 57, Remove the dead component
DocsLayoutChunks and its commented-out usage: locate the DocsLayoutChunks
declaration and any commented code that references it, delete the unused
function (and the commented lines that indicate its former usage) or, if it was
intended to be used, restore and implement the component properly; ensure no
remaining imports or references to DocsLayoutChunks remain to avoid
unused-symbol warnings.
docs/app/docs/components/accordion/docs/component_api/root.tsx (1)

1-136: Consider adding TypeScript types for the documentation data structure.

Since this is a .tsx file, adding a type definition for the table schema would improve type safety and IDE support across all API documentation files.

♻️ Example type definition
interface PropDoc {
    prop: { name: string; info_tooltips: string };
    type: string;
    enum_values?: string[];
    default: string;
}

interface ApiTableData {
    name: string;
    description: string;
    columns: { name: string; id: string }[];
    data: PropDoc[];
}

const data: ApiTableData = {
    // ... existing content
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/docs/components/accordion/docs/component_api/root.tsx` around lines
1 - 136, Add TypeScript types for the documentation structure to improve type
safety: declare interfaces like PropDoc (with prop:{name:string;
info_tooltips:string}, type:string, enum_values?:string[], default:string) and
ApiTableData (name:string, description:string, columns:{name:string;
id:string}[], data:PropDoc[]), then annotate the existing constant by changing
its declaration to use that type (i.e., keep the identifier data but declare it
as ApiTableData) and ensure export default data remains; update any mismatched
fields to satisfy the interfaces (e.g., optional enum_values) in the file that
defines data.
docs/tsconfig.json (1)

19-19: Consider re-enabling incremental compilation for docs DX

Line 19 sets incremental to false. This is valid, but it usually slows repeated local type-check cycles by disabling .tsbuildinfo reuse. If there isn’t a specific reason (e.g., deterministic CI-only behavior), true is generally the better default.

Suggested change
-    "incremental": false,
+    "incremental": true,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/tsconfig.json` at line 19, The tsconfig setting "incremental" is
currently false which disables .tsbuildinfo reuse and slows local type-check
cycles; change the "incremental" option in docs/tsconfig.json from false to true
(i.e., set the "incremental" property to true) so TypeScript produces and reuses
.tsbuildinfo for faster repeated builds unless there is a documented reason to
keep it disabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/app/docs/components/toggle-group/docs/examples/ToggleGroupExample.tsx`:
- Around line 8-13: The current items array uses non-descriptive values like
'item1' that are being used as aria-labels; update the items array (the const
items in ToggleGroupExample.tsx) so each entry includes a descriptive ariaLabel
(or use a descriptive string for value) such as "square view", "crop tool",
"layers view", "columns view", and then update the ToggleGroup Item usage (where
Item consumes item.value/label) to set aria-label={item.ariaLabel || item.value}
so screen readers receive meaningful context; ensure the unique symbols items
and Item in ToggleGroupExample.tsx are updated accordingly.

In `@docs/app/docs/layout.tsx`:
- Around line 33-40: PageDetails is being rendered twice causing duplicate
output; remove one of the two renderings so it appears only once — either delete
the PageDetails component instance inside the Layout wrapper (the <PageDetails
/> currently rendered before DocsLayoutJoinDiscordCallout) or remove the
PageDetails usage inside the DocsLayoutGridRoot component (the other rendering),
depending on where you want SEO/page details to reside; update only the
redundant JSX reference (PageDetails) so the remaining single instance provides
the page metadata.

In `@docs/app/landingComponents/ToolbarDemo.js`:
- Around line 94-96: The demo's search input in ToolbarDemo.js is currently
focusable but non-functional; remove the no-op onChange handler and make the
element explicitly non-interactive by adding readOnly and tabIndex={-1} (or
replace the <input> with a non-form element like a <div> styled the same) so it
no longer appears interactive or receives keyboard focus; update the JSX for the
input element accordingly where the demo input is rendered.

In `@docs/app/page.tsx`:
- Around line 225-258: The demo cluster mounts live interactive components
(FloatingSurface with MusicAppPlayerDemo, AddToCartDemo, TrafficAnalyticsDemo,
YourTeamDemo) which makes the hero non-decorative and keyboard-focusable; change
these to be inert and provide a static, non-animated fallback for users who
prefer reduced motion. Concretely: update the FloatingSurface instances (or the
FloatingSurface component) to set aria-hidden="true", tabIndex={-1} (or use the
inert attribute/polyfill) and pointer-events: none so they are non-focusable and
non-interactive, and detect prefers-reduced-motion (via
window.matchMedia("(prefers-reduced-motion: reduce)") or a useReducedMotion
hook) to render a static snapshot component instead of the live demos and to
disable animations/transition props when reduced motion is requested. Ensure the
static fallback components are simple presentational markup (no controls) named
clearly (e.g., MusicAppPlayerDemoStatic) and use those in place of
MusicAppPlayerDemo etc. when reduced motion is true.
- Line 235: The Tailwind class "opacity-26" in the JSX className string is
invalid and will be ignored; update the className value to use a valid utility
such as "opacity-25" or the arbitrary value "opacity-[0.26]" (e.g., replace
opacity-26 inside the className attribute) so the intended opacity is applied.

In `@docs/app/showcase/music-app/helpers/sections/PlaylistHero.tsx`:
- Around line 42-51: The album cover images are only interactive via
onMouseEnter so keyboard and touch users cannot select them; update the mapped
element in PlaylistHero to be an accessible interactive control by making each
cover focusable (add tabIndex=0 or convert to a button) and add onFocus/onBlur
handlers that call setIndexHovered(index) and clear it, add onKeyDown to handle
Enter/Space to activate the same selection logic, and add onClick for touch
support; also expose state to screen readers with an appropriate attribute
(aria-pressed or aria-current) using indexHovered and keep existing className
toggles intact so visual styles still update.
- Around line 75-77: The search input in PlaylistHero (the <input> inside the
label in PlaylistHero.tsx) lacks an accessible name; update the input to provide
an explicit accessible name by either adding an appropriate aria-label (e.g.,
aria-label="Search artists, albums, moods") or by giving the input an id and
associating a visible or screen-reader-only <label> element with that id so
screen readers can reliably identify the control; ensure the label text matches
the placeholder intent and that no duplicate IDs are introduced.

In `@docs/app/showcase/music-app/helpers/sections/TopArtists.tsx`:
- Line 88: The article in TopArtists.tsx currently uses the CSS class
'cursor-pointer' which implies interactivity but the <article> has no
click/keyboard handlers; either remove 'cursor-pointer' from the class list to
make it purely presentational, or convert the <article> into a proper
interactive element (e.g., a <button> or <a>) and add the corresponding onClick
and keyboard handling and ARIA/semantic attributes so it is accessible; locate
the element rendering the card (the <article> with classes including 'group
cursor-pointer ...') and apply one of these two changes consistently across the
TopArtists card component.
- Around line 132-134: The map over quickQueue currently uses track.title as the
React key (in quickQueue.map(...) producing the div with key={track.title}),
which can collide for duplicate titles; update the key to a collision-resistant
unique identifier such as track.id if available, otherwise fallback to a stable
composite (e.g., `${track.id ?? track.title}-${index}`) or generate a UUID
upstream, and replace the key assignment on the div accordingly so
reconciliation uses a unique, stable key.

In `@docs/components/Copy.js`:
- Around line 25-28: The icon-only button in the Copy component is missing
button semantics and an accessible name; update the <button> in the JSX (the
element using handleCopy, className, isCopied, Check/CopyIcon, iconSize) to
include type="button" and an aria-label (either a passed-in prop like ariaLabel
or a sensible default such as "Copy" and change dynamically to "Copied" when
isCopied is true) so screen readers get a clear name and the button won't submit
forms accidentally.

In `@docs/components/layout/Documentation/helpers/CodeBlock.js`:
- Around line 42-48: The conditional early return for inline in CodeBlock()
occurs after useState/useRef but before useEffect, violating the Rules of Hooks;
fix by moving the inline-mode early return to the top of the CodeBlock component
so it runs before any hooks are declared (or alternatively ensure useEffect is
always called by moving/adding a no-op useEffect above the inline check),
referencing the inline prop and the component's hooks (useState/useRef and
useEffect) so hooks execute in the same order every render.

In `@docs/components/Main/NavBar/helpers/NavRoot/index.tsx`:
- Line 72: The current docs detection uses pathname?.startsWith("/docs") which
matches unwanted routes like "/docs-old"; update the logic in the NavRoot helper
(the isDocsPage calculation) to perform a segment-aware match such as testing
pathname against a regex that requires "/docs" to be a full segment (e.g.
/^\/docs(?:\/|$)/) or by splitting pathname on "/" and checking the first
non-empty segment equals "docs", then set isDocsPage based on that stricter
check so docs-specific nav behavior only applies to /docs and its children.

In `@docs/components/PostHogProvider.tsx`:
- Around line 19-26: The variable postHogKey used in the call to posthog.init
may be string | undefined and TypeScript cannot rely on the module-level
hasPostHogKey to narrow it; update the initialization to perform an inline
null/placeholder guard inside the effect that calls posthog.init (e.g., in the
same useEffect where posthog.init is invoked) so TypeScript sees a concrete
string before calling posthog.init(postHogKey, ...), or alternatively use a
non-null assertion when calling posthog.init if you are certain it cannot be
undefined; reference postHogKey, hasPostHogKey and posthog.init in
PostHogProvider.tsx to locate the change.

In `@docs/mdx-components.tsx`:
- Around line 41-49: The current pre renderer drops non-string ReactNode code
children by using '' fallback; update the logic in the pre component (the
isValidElement(children) branch where childProps and language are computed) to
normalize ReactNode content into a single string before passing to
Documentation.CodeBlock: use React.Children.toArray(childProps.children) to
flatten fragments/arrays, map each item to a string (e.g., keep strings, call
String(...) for numbers/other primitives, and ignore null/undefined), join the
parts into one codeContent string, and pass that as the child to
<Documentation.CodeBlock
language={language}>{codeContent}</Documentation.CodeBlock>; also ensure React
is imported if not already.

In `@docs/tsconfig.json`:
- Around line 40-42: The tsconfig.json currently lists ".next" under the
"exclude" array which prevents the explicit "include" entries
".next/types/**/*.ts" and ".next/dev/types/**/*.ts" from being honored; remove
".next" from the "exclude" array (keep "node_modules") so the included
Next-generated type files (referenced in the "include" section) are discovered
by the compiler, ensuring the "exclude" and "include" keys in tsconfig.json
behave correctly.

In `@docs/types/custom.d.ts`:
- Around line 7-19: The current ToggleGroupRootProps and ToggleGroupItemProps
use overly loose unknown types for value/defaultValue/onValueChange and make
item value optional; change them to a discriminated union keyed on the type prop
so that when ToggleGroupRootProps.type === 'single' the root's
value/defaultValue/onValueChange are string and when type === 'multiple' they
are string[] (and corresponding onValueChange signatures), and update
ToggleGroupItemProps to require value: string and iconOnly/children as before;
update any generics or usages to match the new discriminated union and ensure
ToggleGroupItemProps.value is no longer optional.

---

Outside diff comments:
In `@docs/components/ui/Tooltip/index.tsx`:
- Around line 9-17: TooltipWrapper currently always renders <Tooltip.Content>
which can produce empty tooltips when the optional label prop is omitted; update
TooltipWrapper so that Tooltip.Content is rendered only when label is non-empty
(i.e., check truthiness of the label prop before rendering Tooltip.Content).
Locate the TooltipWrapper component and replace the unconditional
Tooltip.Content with a conditional render (render Tooltip.Content with the label
only when label is present) to avoid empty tooltips. Ensure you preserve the
existing placement prop and other props passed into <Tooltip.Root> and keep the
Trigger asChild behavior unchanged.

---

Nitpick comments:
In `@docs/app/docs/components/accordion/content.mdx`:
- Around line 5-8: Remove the four consecutive blank lines in the Accordion
content MDX file and collapse them to a single blank line for consistency; open
the "content.mdx" for the accordion component (the MDX document that contains
the accordion content) and delete the extra empty lines so only one blank line
remains between sections or before the next block.

In `@docs/app/docs/components/accordion/docs/component_api/root.tsx`:
- Around line 1-136: Add TypeScript types for the documentation structure to
improve type safety: declare interfaces like PropDoc (with prop:{name:string;
info_tooltips:string}, type:string, enum_values?:string[], default:string) and
ApiTableData (name:string, description:string, columns:{name:string;
id:string}[], data:PropDoc[]), then annotate the existing constant by changing
its declaration to use that type (i.e., keep the identifier data but declare it
as ApiTableData) and ensure export default data remains; update any mismatched
fields to satisfy the interfaces (e.g., optional enum_values) in the file that
defines data.

In `@docs/app/docs/components/callout/examples/CalloutExample.tsx`:
- Around line 8-17: The JSX in CalloutExample (Callout.Root, Callout.Icon,
Callout.Text) has inconsistent indentation—align the opening <Callout.Root> tag,
its child elements (<Callout.Icon>, <Callout.Text>) and the closing
</Callout.Root> with the component declaration so the indentation level is
consistent; update the whitespace so children are indented one level inside
Callout.Root and the closing tag lines up with the component name to match the
project formatting pattern.

In `@docs/app/docs/components/dialog/docs/component_api/root.tsx`:
- Around line 51-57: Remove the "defaultOpen" row from the standard prop table
(the prop entry where prop.name is "defaultOpen") and instead add a short "Not
supported / differences from Radix" note in the component's API docs explaining
that defaultOpen is not supported on this wrapper and how to control initial
state via external state; update any tooltip or type/default references for
"defaultOpen" so they only appear in that note section and not as a regular prop
entry.

In `@docs/app/docs/components/toggle-group/docs/component_api/item.tsx`:
- Line 32: The docs currently declare the prop type for value as the generic
"any"; update the value prop to a specific type (e.g., string | number or string
| number | boolean) or, better, reference the actual component prop type (e.g.,
ToggleItemProps['value'] or ToggleGroupItemProps['value']) so consumers see the
real accepted types; change the type entry for value in the item component API
from "any" to the chosen union or the referenced prop type and run the
type-check/build to confirm the docs reflect the corrected type.

In `@docs/app/docs/components/toggle-group/docs/toggle-group-example-basic.tsx`:
- Around line 18-24: The aria-labels for ToggleGroup.Item are currently using
item.value (e.g., "item1") which is not descriptive; update the items data to
include a descriptive property (e.g., ariaLabel) and change the ToggleGroup.Item
prop to use aria-label={item.ariaLabel} so screen readers receive meaningful
labels; locate the items array and the ToggleGroup.Item usage in the example and
ensure each item has an ariaLabel string that describes the icon's purpose and
is referenced by ToggleGroup.Item.

In `@docs/app/docs/layout.tsx`:
- Around line 55-57: Remove the dead component DocsLayoutChunks and its
commented-out usage: locate the DocsLayoutChunks declaration and any commented
code that references it, delete the unused function (and the commented lines
that indicate its former usage) or, if it was intended to be used, restore and
implement the component properly; ensure no remaining imports or references to
DocsLayoutChunks remain to avoid unused-symbol warnings.

In `@docs/app/globals.scss`:
- Around line 62-65: The .function-variable selector is missing the code prefix
and may apply styles outside code blocks; update the selector list used for
syntax highlighting to include the code-scoped selector (i.e., change the rule
that currently targets "code .function, .function-variable" to target "code
.function, code .function-variable" or equivalent) so both .function and
.function-variable are only styled inside code elements; modify the rule where
.function-variable is declared to use the code-prefixed selector.

In `@docs/app/playground/components/HeadingPlayground.js`:
- Line 9: Remove the obsolete loop={false} prop from the ColorLooper usage in
HeadingPlayground.js—locate the JSX where ColorLooper is rendered (identifier:
ColorLooper) and delete the loop prop so the component call only includes props
that ColorLooper actually accepts.

In `@docs/app/playground/components/SeparatorPlayground.js`:
- Line 33: Replace the relative date string "Updated today" inside the
SeparatorPlayground.js component (the Text/Em element that currently renders
that copy) with a concrete date or derive it from page metadata; update the
Text/Em node so it either renders a fixed month/year (e.g., "Updated March
2026") or reads a timestamp prop/metadata value (e.g., lastUpdated) and formats
that, ensuring the displayed text is not time-relative and will not become
stale.

In `@docs/app/playground/page.tsx`:
- Around line 32-35: Update the coverage summary text inside the div with class
'grid gap-2 text-sm text-gray-700 md:max-w-xs' (the two span elements rendered
in page.tsx) so it lists all demos actually rendered below: include avatar,
badge, button, typography, separator, blockquote, code, heading, em, link and
text; change the first span content from the current subset to the full,
accurate list and keep the second span about focus unchanged.

In `@docs/app/showcase/music-app/helpers/MusicPlayer.tsx`:
- Around line 21-27: IconContainerSmall is typed with `any` which disables type
safety; replace `any` by defining a props interface like `interface
IconContainerSmallProps { children: React.ReactNode; }` and annotate the
component signature to use that interface and proper return type (e.g., `const
IconContainerSmall: React.FC<IconContainerSmallProps>` or `: JSX.Element`),
ensuring you import React types if needed and remove all `any` usages in that
file.
- Around line 33-38: Extract the inline pause markup into a reusable PauseIcon
component (or const PauseIcon = () => ...) and replace the nested JSX inside the
ternary with <PauseIcon /> to match the existing PlayIcon pattern; update the
MusicPlayer button JSX (the onClick uses setIsPlaying and the ternary checking
isPlaying) to render <PauseIcon /> when isPlaying is true and keep <PlayIcon />
when false, ensuring you export/import PauseIcon similarly to PlayIcon and
preserve existing classes/spacing.

In `@docs/app/showcase/music-app/helpers/MusicSidebar.js`:
- Around line 25-29: The returned button in MusicSidebar.js currently lacks an
explicit type, so when rendered inside a form it will act as a submit button;
update the JSX for the button element returned by the component (the <button
...> in the render/return of MusicSidebar) to include type="button" to prevent
unintended form submissions while preserving the existing className and props.

In `@docs/app/showcase/music-app/helpers/sections/PlaylistHero.tsx`:
- Around line 36-37: Replace the loose `any` return/type annotations with
explicit React element types: change the component declaration for
InteractiveAlbums to return React.JSX.Element (e.g., `const InteractiveAlbums =
(): React.JSX.Element => ...`) and do the same for the other component(s) in
this file that currently use `any` (the declaration around line 62), ensuring
component signatures use React.JSX.Element instead of `any`.

In `@docs/app/showcase/music-app/helpers/sections/TopArtists.tsx`:
- Line 86: The Artist component is typed as any which loses safety when
accessing artist.genre, artist.monthly, and artist.album; create explicit
TypeScript types (e.g., interface ArtistData { id: string; name: string; genre:
string; monthly: number; album: string; image?: string } and type ArtistProps =
{ artist: ArtistData; index: number }) and replace the any usages on the Artist
component signature and on the arrays that feed it (the top artists data
array(s)) so the component and data are strongly typed and property access is
validated by the compiler.

In
`@docs/components/layout/Documentation/helpers/ComponentFeatures/ComponentFeatures.js`:
- Around line 17-19: The list items use key={index} in the features.map
rendering which can cause UI state bugs when items reorder; update the <li> key
to use a stable unique identifier from the feature object (e.g., feature.id,
feature.key, or a unique feature.title/name) in the ComponentFeatures mapping
instead of the array index, and if no stable property exists add a unique id to
each feature when the data is created so the key remains consistent across
re-renders.

In `@docs/tsconfig.json`:
- Line 19: The tsconfig setting "incremental" is currently false which disables
.tsbuildinfo reuse and slows local type-check cycles; change the "incremental"
option in docs/tsconfig.json from false to true (i.e., set the "incremental"
property to true) so TypeScript produces and reuses .tsbuildinfo for faster
repeated builds unless there is a documented reason to keep it disabled.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d46362d-a824-418a-829c-aa2f842f2806

📥 Commits

Reviewing files that changed from the base of the PR and between 84597c0 and e825180.

⛔ Files ignored due to path filters (1)
  • docs/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (181)
  • README.md
  • docs/app/docs/components/accordion/content.mdx
  • docs/app/docs/components/accordion/docs/codeUsage.js
  • docs/app/docs/components/accordion/docs/component_api/content.tsx
  • docs/app/docs/components/accordion/docs/component_api/header.tsx
  • docs/app/docs/components/accordion/docs/component_api/item.tsx
  • docs/app/docs/components/accordion/docs/component_api/root.tsx
  • docs/app/docs/components/accordion/docs/component_api/trigger.tsx
  • docs/app/docs/components/accordion/docs/example_1.tsx
  • docs/app/docs/components/accordion/page.tsx
  • docs/app/docs/components/alert-dialog/content.mdx
  • docs/app/docs/components/alert-dialog/docs/anatomy.tsx
  • docs/app/docs/components/alert-dialog/docs/codeUsage.js
  • docs/app/docs/components/alert-dialog/docs/component_api/content.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/description.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/footer.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/overlay.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/portal.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/root.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/title.tsx
  • docs/app/docs/components/alert-dialog/docs/example_1.tsx
  • docs/app/docs/components/alert-dialog/page.tsx
  • docs/app/docs/components/aspect-ratio/page.tsx
  • docs/app/docs/components/avatar-group/content.mdx
  • docs/app/docs/components/avatar-group/docs/component_api/fallback.tsx
  • docs/app/docs/components/avatar-group/docs/component_api/item.tsx
  • docs/app/docs/components/avatar-group/page.tsx
  • docs/app/docs/components/avatar/docs/component_api/fallback.tsx
  • docs/app/docs/components/avatar/docs/component_api/image.tsx
  • docs/app/docs/components/avatar/page.tsx
  • docs/app/docs/components/badge/examples/BadgeVariants.tsx
  • docs/app/docs/components/badge/page.tsx
  • docs/app/docs/components/blockquote/content.mdx
  • docs/app/docs/components/blockquote/page.tsx
  • docs/app/docs/components/button/content.mdx
  • docs/app/docs/components/button/docs/codeUsage.js
  • docs/app/docs/components/button/examples/ButtonVariants.tsx
  • docs/app/docs/components/button/page.tsx
  • docs/app/docs/components/callout/content.mdx
  • docs/app/docs/components/callout/docs/component_api/root.tsx
  • docs/app/docs/components/callout/examples/CalloutExample.tsx
  • docs/app/docs/components/callout/page.tsx
  • docs/app/docs/components/card/content.mdx
  • docs/app/docs/components/card/docs/codeUsage.js
  • docs/app/docs/components/card/docs/component_api/action.tsx
  • docs/app/docs/components/card/docs/component_api/card.tsx
  • docs/app/docs/components/card/docs/component_api/content.tsx
  • docs/app/docs/components/card/docs/component_api/description.tsx
  • docs/app/docs/components/card/docs/component_api/footer.tsx
  • docs/app/docs/components/card/docs/component_api/header.tsx
  • docs/app/docs/components/card/docs/component_api/root.tsx
  • docs/app/docs/components/card/docs/component_api/title.tsx
  • docs/app/docs/components/card/examples/CardExample.tsx
  • docs/app/docs/components/card/page.tsx
  • docs/app/docs/components/code/content.mdx
  • docs/app/docs/components/code/page.tsx
  • docs/app/docs/components/dialog/content.mdx
  • docs/app/docs/components/dialog/docs/anatomy.tsx
  • docs/app/docs/components/dialog/docs/codeUsage.js
  • docs/app/docs/components/dialog/docs/component_api/close.tsx
  • docs/app/docs/components/dialog/docs/component_api/content.tsx
  • docs/app/docs/components/dialog/docs/component_api/description.tsx
  • docs/app/docs/components/dialog/docs/component_api/footer.tsx
  • docs/app/docs/components/dialog/docs/component_api/overlay.tsx
  • docs/app/docs/components/dialog/docs/component_api/portal.tsx
  • docs/app/docs/components/dialog/docs/component_api/root.tsx
  • docs/app/docs/components/dialog/docs/component_api/title.tsx
  • docs/app/docs/components/dialog/docs/example_1.tsx
  • docs/app/docs/components/dialog/page.tsx
  • docs/app/docs/components/em/content.mdx
  • docs/app/docs/components/em/page.tsx
  • docs/app/docs/components/heading/content.mdx
  • docs/app/docs/components/heading/page.tsx
  • docs/app/docs/components/kbd/content.mdx
  • docs/app/docs/components/kbd/page.tsx
  • docs/app/docs/components/progress/content.mdx
  • docs/app/docs/components/progress/docs/component_api/indicator.tsx
  • docs/app/docs/components/progress/docs/component_api/root.tsx
  • docs/app/docs/components/progress/page.tsx
  • docs/app/docs/components/separator/content.mdx
  • docs/app/docs/components/separator/page.tsx
  • docs/app/docs/components/strong/content.mdx
  • docs/app/docs/components/strong/page.tsx
  • docs/app/docs/components/switch/content.mdx
  • docs/app/docs/components/switch/docs/component_api/root.tsx
  • docs/app/docs/components/switch/docs/component_api/thumb.tsx
  • docs/app/docs/components/switch/page.tsx
  • docs/app/docs/components/table/content.mdx
  • docs/app/docs/components/table/docs/anatomy.tsx
  • docs/app/docs/components/table/docs/component_api/body.tsx
  • docs/app/docs/components/table/docs/component_api/cell.tsx
  • docs/app/docs/components/table/docs/component_api/column-header.tsx
  • docs/app/docs/components/table/docs/component_api/head.tsx
  • docs/app/docs/components/table/docs/component_api/root.tsx
  • docs/app/docs/components/table/docs/component_api/row.tsx
  • docs/app/docs/components/table/page.tsx
  • docs/app/docs/components/tabs/content.mdx
  • docs/app/docs/components/tabs/docs/component_api/content.tsx
  • docs/app/docs/components/tabs/docs/component_api/list.tsx
  • docs/app/docs/components/tabs/docs/component_api/root.tsx
  • docs/app/docs/components/tabs/docs/component_api/trigger.tsx
  • docs/app/docs/components/tabs/page.tsx
  • docs/app/docs/components/text/content.mdx
  • docs/app/docs/components/text/page.tsx
  • docs/app/docs/components/toggle-group/content.mdx
  • docs/app/docs/components/toggle-group/docs/component_api/item.tsx
  • docs/app/docs/components/toggle-group/docs/component_api/root.tsx
  • docs/app/docs/components/toggle-group/docs/examples/ToggleGroupExample.tsx
  • docs/app/docs/components/toggle-group/docs/toggle-group-example-basic.tsx
  • docs/app/docs/components/toggle-group/page.tsx
  • docs/app/docs/components/toggle/docs/toggle-example-basic.tsx
  • docs/app/docs/components/toggle/page.tsx
  • docs/app/docs/components/tooltip/content.mdx
  • docs/app/docs/components/tooltip/docs/component_api/content.tsx
  • docs/app/docs/components/tooltip/docs/component_api/root.tsx
  • docs/app/docs/components/tooltip/docs/component_api/trigger.tsx
  • docs/app/docs/components/tooltip/page.tsx
  • docs/app/docs/components/visually-hidden/content.mdx
  • docs/app/docs/components/visually-hidden/docs/codeUsage.js
  • docs/app/docs/components/visually-hidden/docs/examples/VisuallyHiddenExample.tsx
  • docs/app/docs/components/visually-hidden/page.tsx
  • docs/app/docs/contributing/before-you-start/page.tsx
  • docs/app/docs/contributing/component-coverage/page.tsx
  • docs/app/docs/contributing/component-maturity-rubric/page.tsx
  • docs/app/docs/contributing/contributing-to-rad-ui/page.tsx
  • docs/app/docs/contributing/setting-up-dev-environment/page.tsx
  • docs/app/docs/first-steps/installation/page.tsx
  • docs/app/docs/first-steps/introduction/page.tsx
  • docs/app/docs/first-steps/usage/page.tsx
  • docs/app/docs/guides/accessibility/page.tsx
  • docs/app/docs/guides/component-coverage/page.tsx
  • docs/app/docs/layout.tsx
  • docs/app/globals.scss
  • docs/app/landingComponents/AddToCartDemo.js
  • docs/app/landingComponents/ToolbarDemo.js
  • docs/app/landingComponents/TrafficAnalyticsDemo.js
  • docs/app/landingComponents/YourTeamDemo.js
  • docs/app/layout.js
  • docs/app/not-found.tsx
  • docs/app/page.tsx
  • docs/app/playground/components/AvatarPlayground.js
  • docs/app/playground/components/BadgePlayground.js
  • docs/app/playground/components/BlockquotePlayground.js
  • docs/app/playground/components/ButtonPlayground.js
  • docs/app/playground/components/CodePlayground.js
  • docs/app/playground/components/EmPlayground.js
  • docs/app/playground/components/HeadingPlayground.js
  • docs/app/playground/components/LinkPlayground.js
  • docs/app/playground/components/SeparatorPlayground.js
  • docs/app/playground/components/TextPlayground.js
  • docs/app/playground/helpers/ColorLooper.js
  • docs/app/playground/page.tsx
  • docs/app/showcase/layout.js
  • docs/app/showcase/music-app/helpers/MusicPlayer.tsx
  • docs/app/showcase/music-app/helpers/MusicSidebar.js
  • docs/app/showcase/music-app/helpers/sections/PlaylistHero.tsx
  • docs/app/showcase/music-app/helpers/sections/TopArtists.tsx
  • docs/app/showcase/music-app/page.js
  • docs/components/Copy.js
  • docs/components/Main/NavBar/helpers/NavRoot/index.tsx
  • docs/components/PostHogProvider.tsx
  • docs/components/docsPage/createDocsPage.tsx
  • docs/components/hero/FloatingSurface.tsx
  • docs/components/layout/Documentation/DocsTableOfContents.tsx
  • docs/components/layout/Documentation/Documentation.js
  • docs/components/layout/Documentation/helpers/CodeBlock.js
  • docs/components/layout/Documentation/helpers/ComponentFeatures/ComponentFeatures.js
  • docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js
  • docs/components/layout/Documentation/helpers/ComponentHero/ComponentHero.js
  • docs/components/layout/Documentation/helpers/DocsTable.js
  • docs/components/layout/Documentation/shared.js
  • docs/components/layout/Documentation/utils.js
  • docs/components/seo/PageDetails.tsx
  • docs/components/ui/Tooltip/index.tsx
  • docs/mdx-components.tsx
  • docs/package.json
  • docs/tsconfig.json
  • docs/types/custom.d.ts
  • docs/utils/seo/generateSeoMetadata.ts
  • package.json
  • styles/cssTokens/base.tokens.css
💤 Files with no reviewable changes (2)
  • docs/app/docs/components/badge/examples/BadgeVariants.tsx
  • docs/app/docs/components/card/docs/component_api/card.tsx
✅ Files skipped from review due to trivial changes (59)
  • docs/app/docs/components/table/docs/anatomy.tsx
  • docs/app/docs/components/table/docs/component_api/head.tsx
  • docs/app/docs/components/table/docs/component_api/row.tsx
  • README.md
  • docs/app/docs/components/accordion/docs/component_api/content.tsx
  • docs/app/docs/components/accordion/docs/component_api/header.tsx
  • docs/app/docs/components/accordion/docs/component_api/item.tsx
  • docs/app/docs/components/accordion/docs/component_api/trigger.tsx
  • docs/app/docs/components/alert-dialog/docs/anatomy.tsx
  • docs/app/docs/components/alert-dialog/docs/codeUsage.js
  • docs/app/docs/components/alert-dialog/docs/component_api/description.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/footer.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/overlay.tsx
  • docs/app/docs/components/alert-dialog/docs/component_api/portal.tsx
  • docs/app/docs/components/avatar-group/docs/component_api/fallback.tsx
  • docs/app/docs/components/avatar-group/docs/component_api/item.tsx
  • docs/app/docs/components/avatar/docs/component_api/fallback.tsx
  • docs/app/docs/components/avatar/docs/component_api/image.tsx
  • docs/app/docs/components/blockquote/content.mdx
  • docs/app/docs/components/button/examples/ButtonVariants.tsx
  • docs/app/docs/components/card/docs/component_api/action.tsx
  • docs/app/docs/components/card/docs/component_api/content.tsx
  • docs/app/docs/components/card/docs/component_api/description.tsx
  • docs/app/docs/components/card/docs/component_api/footer.tsx
  • docs/app/docs/components/card/docs/component_api/header.tsx
  • docs/app/docs/components/card/docs/component_api/root.tsx
  • docs/app/docs/components/card/docs/component_api/title.tsx
  • docs/app/docs/components/dialog/docs/anatomy.tsx
  • docs/app/docs/components/dialog/docs/component_api/close.tsx
  • docs/app/docs/components/dialog/docs/component_api/content.tsx
  • docs/app/docs/components/dialog/docs/component_api/footer.tsx
  • docs/app/docs/components/dialog/docs/component_api/portal.tsx
  • docs/app/docs/components/dialog/docs/component_api/title.tsx
  • docs/app/docs/components/dialog/docs/example_1.tsx
  • docs/app/docs/components/em/content.mdx
  • docs/app/docs/components/kbd/content.mdx
  • docs/app/docs/components/progress/docs/component_api/indicator.tsx
  • docs/app/docs/components/separator/content.mdx
  • docs/app/docs/components/strong/content.mdx
  • docs/app/docs/components/table/docs/component_api/body.tsx
  • docs/app/docs/components/tabs/docs/component_api/content.tsx
  • docs/app/docs/components/tabs/docs/component_api/list.tsx
  • docs/app/docs/components/text/content.mdx
  • docs/app/docs/components/toggle-group/docs/component_api/root.tsx
  • docs/app/docs/components/tooltip/docs/component_api/trigger.tsx
  • docs/app/layout.js
  • docs/app/not-found.tsx
  • docs/app/landingComponents/TrafficAnalyticsDemo.js
  • docs/package.json
  • docs/utils/seo/generateSeoMetadata.ts
  • package.json
  • docs/app/docs/components/card/examples/CardExample.tsx
  • docs/app/docs/components/dialog/docs/component_api/overlay.tsx
  • docs/app/docs/components/table/docs/component_api/column-header.tsx
  • docs/app/playground/components/BlockquotePlayground.js
  • docs/components/layout/Documentation/shared.js
  • docs/app/docs/components/toggle/docs/toggle-example-basic.tsx
  • docs/app/showcase/music-app/page.js
  • docs/components/layout/Documentation/utils.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/components/layout/Documentation/helpers/ComponentHero/ComponentHero.js
  • docs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.js

Comment on lines 8 to 13
const items = [
{ label: <FrameIcon/>, value: 'item1' },
{ label: <CropIcon/>, value: 'item2' },
{ label: <LayersIcon/>, value: 'item3' },
{ label: <ColumnsIcon/>, value: 'item4' }
{ label: <Square size={15} strokeWidth={2} />, value: 'item1' },
{ label: <Crop size={15} strokeWidth={2} />, value: 'item2' },
{ label: <Layers3 size={15} strokeWidth={2} />, value: 'item3' },
{ label: <Columns3 size={15} strokeWidth={2} />, value: 'item4' }
];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Non-descriptive aria-label values impact accessibility.

Using item.value (e.g., "item1", "item2") as aria-label provides no meaningful context for screen reader users. Consider using descriptive labels that convey the button's purpose.

♿ Suggested fix for accessibility
 const items = [
-    { label: <Square size={15} strokeWidth={2} />, value: 'item1' },
-    { label: <Crop size={15} strokeWidth={2} />, value: 'item2' },
-    { label: <Layers3 size={15} strokeWidth={2} />, value: 'item3' },
-    { label: <Columns3 size={15} strokeWidth={2} />, value: 'item4' }
+    { label: <Square size={15} strokeWidth={2} />, value: 'item1', ariaLabel: 'Frame' },
+    { label: <Crop size={15} strokeWidth={2} />, value: 'item2', ariaLabel: 'Crop' },
+    { label: <Layers3 size={15} strokeWidth={2} />, value: 'item3', ariaLabel: 'Layers' },
+    { label: <Columns3 size={15} strokeWidth={2} />, value: 'item4', ariaLabel: 'Columns' }
 ];

Then update the Item:

-                <ToggleGroup.Item key={item.value} value={item.value} iconOnly aria-label={item.value}>
+                <ToggleGroup.Item key={item.value} value={item.value} iconOnly aria-label={item.ariaLabel}>

Also applies to: 19-19

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

In `@docs/app/docs/components/toggle-group/docs/examples/ToggleGroupExample.tsx`
around lines 8 - 13, The current items array uses non-descriptive values like
'item1' that are being used as aria-labels; update the items array (the const
items in ToggleGroupExample.tsx) so each entry includes a descriptive ariaLabel
(or use a descriptive string for value) such as "square view", "crop tool",
"layers view", "columns view", and then update the ToggleGroup Item usage (where
Item consumes item.value/label) to set aria-label={item.ariaLabel || item.value}
so screen readers receive meaningful context; ensure the unique symbols items
and Item in ToggleGroupExample.tsx are updated accordingly.

Comment thread docs/app/docs/layout.tsx
Comment on lines +33 to 40
<div className="w-full min-w-0">
<PageDetails />
{children}
<DocsLayoutJoinDiscordCallout />
<article id="docs-article" className="w-full min-w-0">
{children}
</article>
<EditPageOnGithub />
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

PageDetails is rendered twice, causing duplicate output.

PageDetails is rendered both here (line 34) and inside DocsLayoutGridRoot (line 65). This will result in duplicate SEO/page details being displayed.

Suggested fix – remove one instance

Either remove it from Layout:

                 <div className="w-full min-w-0">
-                    <PageDetails />
                     <DocsLayoutJoinDiscordCallout />

Or remove it from DocsLayoutGridRoot (line 65), depending on the intended placement.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="w-full min-w-0">
<PageDetails />
{children}
<DocsLayoutJoinDiscordCallout />
<article id="docs-article" className="w-full min-w-0">
{children}
</article>
<EditPageOnGithub />
</div>
<div className="w-full min-w-0">
<DocsLayoutJoinDiscordCallout />
<article id="docs-article" className="w-full min-w-0">
{children}
</article>
<EditPageOnGithub />
</div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/app/docs/layout.tsx` around lines 33 - 40, PageDetails is being rendered
twice causing duplicate output; remove one of the two renderings so it appears
only once — either delete the PageDetails component instance inside the Layout
wrapper (the <PageDetails /> currently rendered before
DocsLayoutJoinDiscordCallout) or remove the PageDetails usage inside the
DocsLayoutGridRoot component (the other rendering), depending on where you want
SEO/page details to reside; update only the redundant JSX reference
(PageDetails) so the remaining single instance provides the page metadata.

Comment on lines +94 to 96
<input value="Search..." onChange={() => { }} className='flex flex-1 items-center bg-gray-950 px-2 rounded-md border border-gray-700 text-gray-400'>

</input>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, verify the file exists and check its size
wc -l docs/app/landingComponents/ToolbarDemo.js

Repository: rad-ui/ui

Length of output: 98


🏁 Script executed:

# Read the file to see lines 80-110 for context around lines 94-96
sed -n '80,110p' docs/app/landingComponents/ToolbarDemo.js

Repository: rad-ui/ui

Length of output: 786


🏁 Script executed:

# Read the entire file to understand the component structure and purpose
cat -n docs/app/landingComponents/ToolbarDemo.js

Repository: rad-ui/ui

Length of output: 12410


Make the search input explicitly non-interactive since this is a demo component.

The input appears focusable and clickable but doesn't respond to changes. Add readOnly to the input element and remove the no-op onChange handler to prevent confusing UX and keep it out of the tab order, or replace it with a non-form element if it's purely visual chrome.

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

In `@docs/app/landingComponents/ToolbarDemo.js` around lines 94 - 96, The demo's
search input in ToolbarDemo.js is currently focusable but non-functional; remove
the no-op onChange handler and make the element explicitly non-interactive by
adding readOnly and tabIndex={-1} (or replace the <input> with a non-form
element like a <div> styled the same) so it no longer appears interactive or
receives keyboard focus; update the JSX for the input element accordingly where
the demo input is rendered.

Comment thread docs/app/page.tsx
Comment on lines +225 to +258
<div className="relative mx-auto min-h-[760px] w-full max-w-[700px] lg:min-h-[820px]">
<FloatingSurface
className="absolute right-[5%] top-[8%] w-[50%] p-3 z-[2] w-fit"
initial={{ x: -2, y: 4, rotate: 8 }}
animate={{ x: -4, y: 6, rotate: 20 }}
transition={{ duration: 24, repeat: Infinity, repeatType: "reverse", ease: "easeInOut" }}
>
<MusicAppPlayerDemo />
</FloatingSurface>
<FloatingSurface
className="absolute left-[-12%] top-[18%] w-[30%] p-3 z-[1] opacity-26"
initial={{ x: -6, y: 4, rotate: 4 }}
animate={{ x: 6, y: -4, rotate: -2 }}
transition={{ duration: 26, repeat: Infinity, repeatType: "reverse", ease: "easeInOut" }}
>
<AddToCartDemo />
</FloatingSurface>
<FloatingSurface
className="absolute right-[-40%] top-[-6%] w-[54%] p-3 z-[4]"
initial={{ x: 4, y: 8, rotate: 40 }}
animate={{ x: -6, y: -6, rotate: -3 }}
transition={{ duration: 20, repeat: Infinity, repeatType: "reverse", ease: "easeInOut" }}
>
<TrafficAnalyticsDemo />
</FloatingSurface>

<FloatingSurface
className="absolute left-[6%] top-[54%] w-[30%] p-3 z-[5] w-fit"
initial={{ x: 6, y: 6, rotate: -10 }}
animate={{ x: 6, y: -8, rotate: 4 }}
transition={{ duration: 18, repeat: Infinity, repeatType: "reverse", ease: "easeInOut" }}
>
<YourTeamDemo />
</FloatingSurface>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The hero demo cluster should be decorative, not live UI.

These surfaces mount real controls from the demo components and animate them indefinitely. On the homepage that turns decorative art into extra tab stops and motion-heavy content. Please make this cluster inert/non-focusable and provide a static fallback when reduced motion is requested.

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

In `@docs/app/page.tsx` around lines 225 - 258, The demo cluster mounts live
interactive components (FloatingSurface with MusicAppPlayerDemo, AddToCartDemo,
TrafficAnalyticsDemo, YourTeamDemo) which makes the hero non-decorative and
keyboard-focusable; change these to be inert and provide a static, non-animated
fallback for users who prefer reduced motion. Concretely: update the
FloatingSurface instances (or the FloatingSurface component) to set
aria-hidden="true", tabIndex={-1} (or use the inert attribute/polyfill) and
pointer-events: none so they are non-focusable and non-interactive, and detect
prefers-reduced-motion (via window.matchMedia("(prefers-reduced-motion:
reduce)") or a useReducedMotion hook) to render a static snapshot component
instead of the live demos and to disable animations/transition props when
reduced motion is requested. Ensure the static fallback components are simple
presentational markup (no controls) named clearly (e.g.,
MusicAppPlayerDemoStatic) and use those in place of MusicAppPlayerDemo etc. when
reduced motion is true.

Comment thread docs/app/page.tsx
<MusicAppPlayerDemo />
</FloatingSurface>
<FloatingSurface
className="absolute left-[-12%] top-[18%] w-[30%] p-3 z-[1] opacity-26"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Tailwind config entries mentioning opacity / 26 =="
fd -i 'tailwind.config.*' | while read -r file; do
  echo "--- $file ---"
  rg -n -C2 'opacity|26' "$file" || true
done

echo
echo "== Repo usages of opacity-26 =="
rg -n '\bopacity-26\b' || true

Repository: rad-ui/ui

Length of output: 312


🏁 Script executed:

cat docs/tailwind.config.ts

Repository: rad-ui/ui

Length of output: 782


🏁 Script executed:

cat tailwind.config.js

Repository: rad-ui/ui

Length of output: 279


Replace opacity-26 with a valid Tailwind opacity utility.

opacity-26 is not a standard Tailwind utility and is not extended in the config. The class will be silently ignored. Use opacity-25 or opacity-[0.26] instead.

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

In `@docs/app/page.tsx` at line 235, The Tailwind class "opacity-26" in the JSX
className string is invalid and will be ignored; update the className value to
use a valid utility such as "opacity-25" or the arbitrary value "opacity-[0.26]"
(e.g., replace opacity-26 inside the className attribute) so the intended
opacity is applied.

const NavBar = ({ darkMode, setDarkMode, setThemeCookie }) => {
const { isDocsNavOpen, setIsDocsNavOpen } = useContext(NavBarContext);
const pathname = usePathname();
const isDocsPage = pathname?.startsWith("/docs");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Tighten docs route detection to avoid false positives.

pathname?.startsWith("/docs") also matches routes like /docs-old. Use a segment-aware match so docs-specific nav behavior only applies to /docs and its children.

Suggested fix
-  const isDocsPage = pathname?.startsWith("/docs");
+  const isDocsPage = /^\/docs(\/|$)/.test(pathname ?? "");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isDocsPage = pathname?.startsWith("/docs");
const isDocsPage = /^\/docs(\/|$)/.test(pathname ?? "");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/components/Main/NavBar/helpers/NavRoot/index.tsx` at line 72, The
current docs detection uses pathname?.startsWith("/docs") which matches unwanted
routes like "/docs-old"; update the logic in the NavRoot helper (the isDocsPage
calculation) to perform a segment-aware match such as testing pathname against a
regex that requires "/docs" to be a full segment (e.g. /^\/docs(?:\/|$)/) or by
splitting pathname on "/" and checking the first non-empty segment equals
"docs", then set isDocsPage based on that stricter check so docs-specific nav
behavior only applies to /docs and its children.

Comment thread docs/components/PostHogProvider.tsx
Comment thread docs/mdx-components.tsx
Comment thread docs/tsconfig.json
Comment thread docs/types/custom.d.ts
@kotAPI kotAPI merged commit f92a5dd into main Apr 7, 2026
10 checks passed
@kotAPI kotAPI deleted the kotapi/docs-improvements-4-apr-2026 branch April 7, 2026 12:19
@github-actions

github-actions Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Coverage

This report compares the PR with the base branch. "Δ" shows how the PR affects each metric.

Metric PR Δ
Statements 81.46% +0.00%
Branches 64.24% +0.04%
Functions 69.65% +0.00%
Lines 82.82% +0.00%

Coverage improved or stayed the same. Great job!

Run npm run coverage locally for detailed reports and target untested areas to raise these numbers.

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.

1 participant