Docs Revamp - Apr 2026#1743
Conversation
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (48)
📝 WalkthroughWalkthroughUpdates 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 Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
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 | 🟡 MinorRemove unused
useEffectimport.The
useEffecthook 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 indocs/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_KEYThen 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.mdincludes a helpful note: "If the docs app is already using the published package, re-runpnpm 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`` indocs/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.mdaround 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 -->
There was a problem hiding this comment.
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 | 🟡 MinorAvoid rendering empty tooltip content when
labelis omitted.Since
labelis optional now, renderingTooltip.Contentunconditionally 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 usinganytype; 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
PauseIconwould mirror the existingPlayIconimport 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 indexLine 18 uses
key={index}. Iffeaturescan 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: Addtype="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. Addingtype="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 ofanyfor components.Components in this file use
anyfor their type annotations (lines 36 and 62). While the docs directory runs with TypeScript'sstrict: falsemode, explicitly typing return values asReact.JSX.Elementimproves 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
anyfor both component and props, removing TypeScript safety for property access onartist.genre,artist.monthly, andartist.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 obsoleteloopprop fromColorLooperusage.Line 9 passes
loop={false}, butColorLooperno 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 thananyfor thevalueprop.Using
anyweakens 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.
defaultOpenis 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 descriptivearia-labelvalues for better accessibility.Using
item.value(e.g.,"item1") asaria-labeldoesn'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 theToggleGroup.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-variablemissingcodeprefix.The
.function-variableselector lacks thecodeprefix 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:DocsLayoutChunksis unused.This component always returns
nulland 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
.tsxfile, 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 DXLine 19 sets
incrementaltofalse. This is valid, but it usually slows repeated local type-check cycles by disabling.tsbuildinforeuse. If there isn’t a specific reason (e.g., deterministic CI-only behavior),trueis 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
⛔ Files ignored due to path filters (1)
docs/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (181)
README.mddocs/app/docs/components/accordion/content.mdxdocs/app/docs/components/accordion/docs/codeUsage.jsdocs/app/docs/components/accordion/docs/component_api/content.tsxdocs/app/docs/components/accordion/docs/component_api/header.tsxdocs/app/docs/components/accordion/docs/component_api/item.tsxdocs/app/docs/components/accordion/docs/component_api/root.tsxdocs/app/docs/components/accordion/docs/component_api/trigger.tsxdocs/app/docs/components/accordion/docs/example_1.tsxdocs/app/docs/components/accordion/page.tsxdocs/app/docs/components/alert-dialog/content.mdxdocs/app/docs/components/alert-dialog/docs/anatomy.tsxdocs/app/docs/components/alert-dialog/docs/codeUsage.jsdocs/app/docs/components/alert-dialog/docs/component_api/content.tsxdocs/app/docs/components/alert-dialog/docs/component_api/description.tsxdocs/app/docs/components/alert-dialog/docs/component_api/footer.tsxdocs/app/docs/components/alert-dialog/docs/component_api/overlay.tsxdocs/app/docs/components/alert-dialog/docs/component_api/portal.tsxdocs/app/docs/components/alert-dialog/docs/component_api/root.tsxdocs/app/docs/components/alert-dialog/docs/component_api/title.tsxdocs/app/docs/components/alert-dialog/docs/example_1.tsxdocs/app/docs/components/alert-dialog/page.tsxdocs/app/docs/components/aspect-ratio/page.tsxdocs/app/docs/components/avatar-group/content.mdxdocs/app/docs/components/avatar-group/docs/component_api/fallback.tsxdocs/app/docs/components/avatar-group/docs/component_api/item.tsxdocs/app/docs/components/avatar-group/page.tsxdocs/app/docs/components/avatar/docs/component_api/fallback.tsxdocs/app/docs/components/avatar/docs/component_api/image.tsxdocs/app/docs/components/avatar/page.tsxdocs/app/docs/components/badge/examples/BadgeVariants.tsxdocs/app/docs/components/badge/page.tsxdocs/app/docs/components/blockquote/content.mdxdocs/app/docs/components/blockquote/page.tsxdocs/app/docs/components/button/content.mdxdocs/app/docs/components/button/docs/codeUsage.jsdocs/app/docs/components/button/examples/ButtonVariants.tsxdocs/app/docs/components/button/page.tsxdocs/app/docs/components/callout/content.mdxdocs/app/docs/components/callout/docs/component_api/root.tsxdocs/app/docs/components/callout/examples/CalloutExample.tsxdocs/app/docs/components/callout/page.tsxdocs/app/docs/components/card/content.mdxdocs/app/docs/components/card/docs/codeUsage.jsdocs/app/docs/components/card/docs/component_api/action.tsxdocs/app/docs/components/card/docs/component_api/card.tsxdocs/app/docs/components/card/docs/component_api/content.tsxdocs/app/docs/components/card/docs/component_api/description.tsxdocs/app/docs/components/card/docs/component_api/footer.tsxdocs/app/docs/components/card/docs/component_api/header.tsxdocs/app/docs/components/card/docs/component_api/root.tsxdocs/app/docs/components/card/docs/component_api/title.tsxdocs/app/docs/components/card/examples/CardExample.tsxdocs/app/docs/components/card/page.tsxdocs/app/docs/components/code/content.mdxdocs/app/docs/components/code/page.tsxdocs/app/docs/components/dialog/content.mdxdocs/app/docs/components/dialog/docs/anatomy.tsxdocs/app/docs/components/dialog/docs/codeUsage.jsdocs/app/docs/components/dialog/docs/component_api/close.tsxdocs/app/docs/components/dialog/docs/component_api/content.tsxdocs/app/docs/components/dialog/docs/component_api/description.tsxdocs/app/docs/components/dialog/docs/component_api/footer.tsxdocs/app/docs/components/dialog/docs/component_api/overlay.tsxdocs/app/docs/components/dialog/docs/component_api/portal.tsxdocs/app/docs/components/dialog/docs/component_api/root.tsxdocs/app/docs/components/dialog/docs/component_api/title.tsxdocs/app/docs/components/dialog/docs/example_1.tsxdocs/app/docs/components/dialog/page.tsxdocs/app/docs/components/em/content.mdxdocs/app/docs/components/em/page.tsxdocs/app/docs/components/heading/content.mdxdocs/app/docs/components/heading/page.tsxdocs/app/docs/components/kbd/content.mdxdocs/app/docs/components/kbd/page.tsxdocs/app/docs/components/progress/content.mdxdocs/app/docs/components/progress/docs/component_api/indicator.tsxdocs/app/docs/components/progress/docs/component_api/root.tsxdocs/app/docs/components/progress/page.tsxdocs/app/docs/components/separator/content.mdxdocs/app/docs/components/separator/page.tsxdocs/app/docs/components/strong/content.mdxdocs/app/docs/components/strong/page.tsxdocs/app/docs/components/switch/content.mdxdocs/app/docs/components/switch/docs/component_api/root.tsxdocs/app/docs/components/switch/docs/component_api/thumb.tsxdocs/app/docs/components/switch/page.tsxdocs/app/docs/components/table/content.mdxdocs/app/docs/components/table/docs/anatomy.tsxdocs/app/docs/components/table/docs/component_api/body.tsxdocs/app/docs/components/table/docs/component_api/cell.tsxdocs/app/docs/components/table/docs/component_api/column-header.tsxdocs/app/docs/components/table/docs/component_api/head.tsxdocs/app/docs/components/table/docs/component_api/root.tsxdocs/app/docs/components/table/docs/component_api/row.tsxdocs/app/docs/components/table/page.tsxdocs/app/docs/components/tabs/content.mdxdocs/app/docs/components/tabs/docs/component_api/content.tsxdocs/app/docs/components/tabs/docs/component_api/list.tsxdocs/app/docs/components/tabs/docs/component_api/root.tsxdocs/app/docs/components/tabs/docs/component_api/trigger.tsxdocs/app/docs/components/tabs/page.tsxdocs/app/docs/components/text/content.mdxdocs/app/docs/components/text/page.tsxdocs/app/docs/components/toggle-group/content.mdxdocs/app/docs/components/toggle-group/docs/component_api/item.tsxdocs/app/docs/components/toggle-group/docs/component_api/root.tsxdocs/app/docs/components/toggle-group/docs/examples/ToggleGroupExample.tsxdocs/app/docs/components/toggle-group/docs/toggle-group-example-basic.tsxdocs/app/docs/components/toggle-group/page.tsxdocs/app/docs/components/toggle/docs/toggle-example-basic.tsxdocs/app/docs/components/toggle/page.tsxdocs/app/docs/components/tooltip/content.mdxdocs/app/docs/components/tooltip/docs/component_api/content.tsxdocs/app/docs/components/tooltip/docs/component_api/root.tsxdocs/app/docs/components/tooltip/docs/component_api/trigger.tsxdocs/app/docs/components/tooltip/page.tsxdocs/app/docs/components/visually-hidden/content.mdxdocs/app/docs/components/visually-hidden/docs/codeUsage.jsdocs/app/docs/components/visually-hidden/docs/examples/VisuallyHiddenExample.tsxdocs/app/docs/components/visually-hidden/page.tsxdocs/app/docs/contributing/before-you-start/page.tsxdocs/app/docs/contributing/component-coverage/page.tsxdocs/app/docs/contributing/component-maturity-rubric/page.tsxdocs/app/docs/contributing/contributing-to-rad-ui/page.tsxdocs/app/docs/contributing/setting-up-dev-environment/page.tsxdocs/app/docs/first-steps/installation/page.tsxdocs/app/docs/first-steps/introduction/page.tsxdocs/app/docs/first-steps/usage/page.tsxdocs/app/docs/guides/accessibility/page.tsxdocs/app/docs/guides/component-coverage/page.tsxdocs/app/docs/layout.tsxdocs/app/globals.scssdocs/app/landingComponents/AddToCartDemo.jsdocs/app/landingComponents/ToolbarDemo.jsdocs/app/landingComponents/TrafficAnalyticsDemo.jsdocs/app/landingComponents/YourTeamDemo.jsdocs/app/layout.jsdocs/app/not-found.tsxdocs/app/page.tsxdocs/app/playground/components/AvatarPlayground.jsdocs/app/playground/components/BadgePlayground.jsdocs/app/playground/components/BlockquotePlayground.jsdocs/app/playground/components/ButtonPlayground.jsdocs/app/playground/components/CodePlayground.jsdocs/app/playground/components/EmPlayground.jsdocs/app/playground/components/HeadingPlayground.jsdocs/app/playground/components/LinkPlayground.jsdocs/app/playground/components/SeparatorPlayground.jsdocs/app/playground/components/TextPlayground.jsdocs/app/playground/helpers/ColorLooper.jsdocs/app/playground/page.tsxdocs/app/showcase/layout.jsdocs/app/showcase/music-app/helpers/MusicPlayer.tsxdocs/app/showcase/music-app/helpers/MusicSidebar.jsdocs/app/showcase/music-app/helpers/sections/PlaylistHero.tsxdocs/app/showcase/music-app/helpers/sections/TopArtists.tsxdocs/app/showcase/music-app/page.jsdocs/components/Copy.jsdocs/components/Main/NavBar/helpers/NavRoot/index.tsxdocs/components/PostHogProvider.tsxdocs/components/docsPage/createDocsPage.tsxdocs/components/hero/FloatingSurface.tsxdocs/components/layout/Documentation/DocsTableOfContents.tsxdocs/components/layout/Documentation/Documentation.jsdocs/components/layout/Documentation/helpers/CodeBlock.jsdocs/components/layout/Documentation/helpers/ComponentFeatures/ComponentFeatures.jsdocs/components/layout/Documentation/helpers/ComponentHero/CodeTabs.jsdocs/components/layout/Documentation/helpers/ComponentHero/ComponentHero.jsdocs/components/layout/Documentation/helpers/DocsTable.jsdocs/components/layout/Documentation/shared.jsdocs/components/layout/Documentation/utils.jsdocs/components/seo/PageDetails.tsxdocs/components/ui/Tooltip/index.tsxdocs/mdx-components.tsxdocs/package.jsondocs/tsconfig.jsondocs/types/custom.d.tsdocs/utils/seo/generateSeoMetadata.tspackage.jsonstyles/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
| 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' } | ||
| ]; |
There was a problem hiding this comment.
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.
| <div className="w-full min-w-0"> | ||
| <PageDetails /> | ||
| {children} | ||
| <DocsLayoutJoinDiscordCallout /> | ||
| <article id="docs-article" className="w-full min-w-0"> | ||
| {children} | ||
| </article> | ||
| <EditPageOnGithub /> | ||
| </div> |
There was a problem hiding this comment.
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.
| <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.
| <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> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, verify the file exists and check its size
wc -l docs/app/landingComponents/ToolbarDemo.jsRepository: 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.jsRepository: 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.jsRepository: 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.
| <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> |
There was a problem hiding this comment.
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.
| <MusicAppPlayerDemo /> | ||
| </FloatingSurface> | ||
| <FloatingSurface | ||
| className="absolute left-[-12%] top-[18%] w-[30%] p-3 z-[1] opacity-26" |
There was a problem hiding this comment.
🧩 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' || trueRepository: rad-ui/ui
Length of output: 312
🏁 Script executed:
cat docs/tailwind.config.tsRepository: rad-ui/ui
Length of output: 782
🏁 Script executed:
cat tailwind.config.jsRepository: 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"); |
There was a problem hiding this comment.
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.
| 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.
CoverageThis report compares the PR with the base branch. "Δ" shows how the PR affects each metric.
Coverage improved or stayed the same. Great job! Run |
Summary by CodeRabbit
New Features
Documentation
Style
UX