Skip to content

Conversation

@iamdin
Copy link
Member

@iamdin iamdin commented Sep 1, 2025

Clean up merge markers and ensure displayName on components. Update sheet footer/header, select separator, menu shortcut, input, label, dialog. Typecheck passes for @ui/react.

Summary by CodeRabbit

  • Refactor
    • Standardized public prop typings to HTMLArkProps across many UI components for more consistent TypeScript DX.
    • Updated forwardRef signatures to align with the new typings.
    • Extended sheet anatomy to include header/footer and per-part attribute propagation (no visual or runtime changes).
    • Added Input.displayName for improved dev tooling.
    • No user-facing behavioral or visual changes.

Clean up merge markers and ensure displayName on components. Update sheet footer/header, select separator, menu shortcut, input, label, dialog. Typecheck passes for @ui/react.
@changeset-bot
Copy link

changeset-bot bot commented Sep 1, 2025

⚠️ No Changeset found

Latest commit: 02e9f49

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.

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
Copy link

coderabbitai bot commented Sep 1, 2025

Walkthrough

Replaces PolymorphicProps/HTMLProps with Ark UI’s HTMLArkProps across many React UI components and updates forwardRef generics; preserves runtime rendering. Separately, the Sheet implementation is refactored to an anatomy-driven design with header/footer parts and per-part attrs.

Changes

Cohort / File(s) Summary
Ark UI props typing migration
packages/react/src/components/ui/badge.tsx, packages/react/src/components/ui/button.tsx, packages/react/src/components/ui/dialog.tsx, packages/react/src/components/ui/input.tsx, packages/react/src/components/ui/label.tsx, packages/react/src/components/ui/menu.tsx, packages/react/src/components/ui/pagination.tsx, packages/react/src/components/ui/pin-input.tsx, packages/react/src/components/ui/select.tsx, packages/react/src/components/ui/textarea.tsx, apps/www/public/r/react/*.json
Replaced imports of type HTMLProps and type PolymorphicProps with type HTMLArkProps (from @ark-ui/react/factory) and updated component prop types/forwardRef generics to use HTMLArkProps<...>; runtime JSX (ark.*) and behavior unchanged. Input.displayName = "Input" added.
Sheet anatomy & per-part attrs refactor
apps/www/public/r/react/sheet.tsx, packages/react/src/components/ui/sheet.tsx
Extended sheetAnatomy with header and footer; converted sheet subcomponents to consume parts.*.attrs (backdrop, positioner, content, header, footer, description, title, trigger, closeTrigger), added forwardRef wrappers for triggers/footer/header, introduced side prop for SheetContent placement, adjusted classes/attrs; typing imports migrated to HTMLArkProps.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant SheetAPI as Sheet (public)
  participant Parts as sheetAnatomy/parts
  participant Ark as Ark primitives (Portal/Content/Backdrop)

  User->>SheetAPI: <SheetTrigger/>
  SheetAPI->>Parts: resolve parts.trigger.attrs
  SheetAPI->>Ark: render Trigger with parts.trigger.attrs
  Note over Ark,Parts: On open -> SheetContent renders
  Ark->>Parts: request parts.positioner.attrs, parts.content.attrs, parts.backdrop.attrs
  Ark->>User: mount Portal -> Positioner -> Content -> Backdrop (attrs applied)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A rabbit tinkers with props and parts,
Hop‑stitching types, aligning the charts.
From Poly to Ark I tip my hat,
Parts harmonize, the sheet’s now pat.
A twitch, a nibble — typings set to start. 🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-html-ark-props

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 1, 2025

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
packages/react/src/components/ui/button.tsx (1)

48-56: Set a safe default type="button" to avoid accidental form submissions.

Without this, Button inside forms submits by default.

Apply:

-const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
-  ({ className, variant, size, ...props }, ref) => {
+const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
+  ({ className, variant, size, type = "button", ...props }, ref) => {
     return (
       <ark.button
         ref={ref}
         {...parts.root.attrs}
         className={cn(buttonVariants({ variant, size, className }))}
-        {...props}
+        type={type}
+        {...props}
       />
     )
   }
 )
🧹 Nitpick comments (10)
packages/react/src/components/ui/textarea.tsx (1)

6-6: Migration to HTMLArkProps looks solid.

Types align with Ark UI, ref type is correct, and runtime stays unchanged.

Consider exporting a Props alias for consumers:

+export type TextareaProps = HTMLArkProps<"textarea">

Also applies to: 15-16

packages/react/src/components/ui/pagination.tsx (1)

3-3: Good switch to HTMLArkProps on PaginationContent.

Public typing is consistent with the rest of the PR; ark.ul usage is correct.

Add a named props type for discoverability:

+export type PaginationContentProps = HTMLArkProps<"ul">

Also applies to: 32-35

packages/react/src/components/ui/dialog.tsx (1)

6-6: DialogHeader typing update is correct; consider aligning Footer for consistency.

Header now cleanly uses HTMLArkProps<"div"> with ark.div. Footer still uses plain div and doesn’t forward refs.

Unify Footer with the same pattern:

-const DialogFooter = ({
-  className,
-  ...props
-}: React.HTMLAttributes<HTMLDivElement>) => (
-  <div
-    className={cn(
-      "flex flex-col-reverse gap-3 sm:flex-row sm:justify-end",
-      className
-    )}
-    {...props}
-  />
-)
+const DialogFooter = React.forwardRef<HTMLDivElement, HTMLArkProps<"div">>(
+  ({ className, ...props }, ref) => (
+    <ark.div
+      ref={ref}
+      className={cn(
+        "flex flex-col-reverse gap-3 sm:flex-row sm:justify-end",
+        className
+      )}
+      {...props}
+    />
+  )
+)

Optionally also export a props alias:

+export type DialogHeaderProps = HTMLArkProps<"div">

Also applies to: 85-94, 73-84

packages/react/src/components/ui/label.tsx (1)

6-6: Label props migration is correct; ref and htmlFor are properly handled.

No functional changes and ARIA/attrs passthrough remains intact.

Export a props alias for API consistency:

+export type LabelProps = HTMLArkProps<"label">

Also applies to: 13-28

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

6-6: Input migration + displayName addition LGTM.

Destructure of type with late {...props} avoids override; conditional classes for search/file are fine.

  • Export a props alias for consistency:
+export type InputProps = HTMLArkProps<"input">
  • If you plan variants (size, density), consider extracting classes to CVA later for maintainability.

Also applies to: 13-34

packages/react/src/components/ui/menu.tsx (1)

151-165: MenuShortcut refactor LGTM; optional DX nit: export a props alias.

Small consistency win with other components that export Props.

Apply:

-const MenuShortcut = React.forwardRef<HTMLSpanElement, HTMLArkProps<"span">>(
+type MenuShortcutProps = HTMLArkProps<"span">
+const MenuShortcut = React.forwardRef<HTMLSpanElement, MenuShortcutProps>(
packages/react/src/components/ui/pin-input.tsx (2)

41-44: Unify ref generic style (nit).

Elsewhere in this PR (e.g., MenuShortcut) uses concrete DOM ref types. Consider aligning for consistency.

-const PinInputGroup = React.forwardRef<
-  React.ElementRef<"div">,
-  HTMLArkProps<"div">
+const PinInputGroup = React.forwardRef<
+  HTMLDivElement,
+  HTMLArkProps<"div">
 >(({ className, ...props }, ref) => (

Optionally export the props alias:

+type PinInputGroupProps = HTMLArkProps<"div">
-const PinInputGroup = React.forwardRef<HTMLDivElement, HTMLArkProps<"div">>(
+const PinInputGroup = React.forwardRef<HTMLDivElement, PinInputGroupProps>(

86-89: Apply the same consistency tweak to Separator.

Mirror the ref generic and optional props alias.

-const PinInputSeparator = React.forwardRef<
-  React.ElementRef<"div">,
-  HTMLArkProps<"div">
+const PinInputSeparator = React.forwardRef<
+  HTMLDivElement,
+  HTMLArkProps<"div">
 >((props, ref) => (

Optional:

+type PinInputSeparatorProps = HTMLArkProps<"div">
-const PinInputSeparator = React.forwardRef<HTMLDivElement, HTMLArkProps<"div">>(
+const PinInputSeparator = React.forwardRef<HTMLDivElement, PinInputSeparatorProps>(
packages/react/src/components/ui/button.tsx (1)

21-23: Use semantic token for destructive foreground (avoid text-white).

Aligns with “use semantic design tokens”; improves theming.

Apply:

-        destructive:
-          "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
+        destructive:
+          "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
packages/react/src/components/ui/sheet.tsx (1)

39-42: Minor: cn(className) is a no-op; pass className directly.

Tiny clean-up; no behavioral change.

Apply:

-    className={cn(className)}
+    className={className}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 237133f and 83b371c.

📒 Files selected for processing (11)
  • packages/react/src/components/ui/badge.tsx (2 hunks)
  • packages/react/src/components/ui/button.tsx (2 hunks)
  • packages/react/src/components/ui/dialog.tsx (2 hunks)
  • packages/react/src/components/ui/input.tsx (1 hunks)
  • packages/react/src/components/ui/label.tsx (1 hunks)
  • packages/react/src/components/ui/menu.tsx (2 hunks)
  • packages/react/src/components/ui/pagination.tsx (2 hunks)
  • packages/react/src/components/ui/pin-input.tsx (3 hunks)
  • packages/react/src/components/ui/select.tsx (2 hunks)
  • packages/react/src/components/ui/sheet.tsx (2 hunks)
  • packages/react/src/components/ui/textarea.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/code-standards.mdc)

**/*.{tsx,vue}: Component variable and function names must use PascalCase (e.g. Button, ToggleGroup)
Prefer Tailwind built-in classes for styling
Use semantic design tokens for styling
Support dark theme in component styles
Use Ark UI components as foundation for accessibility
Support keyboard navigation in components
Provide appropriate ARIA attributes in components
Support screen readers in components
Avoid unnecessary re-renders in components
Handle event listeners properly in components

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/code-standards.mdc)

**/*.{ts,tsx}: Function names must use camelCase (e.g. buttonVariants, cn)
Constant names must use SCREAMING_SNAKE_CASE (e.g. DEFAULT_VARIANT)
Type interfaces must use PascalCase with Props suffix (e.g. ButtonProps)

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/code-standards.mdc)

Organize complex styles through CVA (Class Variance Authority)

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/react/src/components/ui/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/component-development.mdc)

packages/react/src/components/ui/*.tsx: React components are located in packages/react/src/components/ui/, using single-file architecture: one .tsx file per component
React components use class-variance-authority (CVA) to manage style variants
React components are built on top of Ark UI components
React components support forwardRef and complete TypeScript types
Define component variants through CVA

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
{packages/react/src/components/ui/*.tsx,packages/vue/src/components/ui/*/*.vue}

📄 CodeRabbit inference engine (.cursor/rules/component-development.mdc)

{packages/react/src/components/ui/*.tsx,packages/vue/src/components/ui/*/*.vue}: Use Tailwind CSS for styling
Use cn() utility function to merge class names
Support custom className overrides

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/{react,vue}/src/components/ui/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.cursor/rules/overview.mdc)

Use TypeScript for complete type safety across the codebase

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/{react,vue}/src/components/ui/**/*

📄 CodeRabbit inference engine (.cursor/rules/overview.mdc)

packages/{react,vue}/src/components/ui/**/*: Ensure all UI components are accessible, leveraging Ark UI for accessibility features
Use Tailwind CSS and CVA for component customization and styling

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
**/*.{js,jsx,ts,tsx,json,jsonc}

📄 CodeRabbit inference engine (.cursor/rules/overview.mdc)

Maintain code quality and style as configured in biome.jsonc

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/react/**

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

React component code must be located under packages/react/

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/{react,vue}/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place framework-specific component implementations under packages/react and packages/vue

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/{react,vue}/**

📄 CodeRabbit inference engine (AGENTS.md)

Place framework-specific component implementations under packages/react and packages/vue

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
packages/{react,vue}/src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Build components on top of Ark UI primitives in framework source code

Files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are built on top of Ark UI components
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to **/*.{tsx,vue} : Use Ark UI components as foundation for accessibility
Learnt from: CR
PR: shipbase/ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-30T18:56:37.501Z
Learning: Build components on top of Ark UI primitives
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/overview.mdc:0-0
Timestamp: 2025-08-03T17:49:50.919Z
Learning: Applies to packages/{react,vue}/src/components/ui/**/* : Ensure all UI components are accessible, leveraging Ark UI for accessibility features
Learnt from: CR
PR: shipbase/ui#0
File: AGENTS.md:0-0
Timestamp: 2025-08-30T18:58:30.749Z
Learning: Applies to packages/{react,vue}/src/**/*.{ts,tsx,vue} : Build components on top of Ark UI primitives in framework source code
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components support forwardRef and complete TypeScript types
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-03T17:50:06.904Z
Learning: The project must use Ark UI as the component library
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are built on top of Ark UI components

Applied to files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components support forwardRef and complete TypeScript types

Applied to files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
📚 Learning: 2025-08-30T18:58:30.749Z
Learnt from: CR
PR: shipbase/ui#0
File: AGENTS.md:0-0
Timestamp: 2025-08-30T18:58:30.749Z
Learning: Applies to packages/{react,vue}/src/**/*.{ts,tsx,vue} : Build components on top of Ark UI primitives in framework source code

Applied to files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
📚 Learning: 2025-08-30T18:56:37.501Z
Learnt from: CR
PR: shipbase/ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-30T18:56:37.501Z
Learning: Build components on top of Ark UI primitives

Applied to files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
📚 Learning: 2025-08-03T17:49:16.881Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to **/*.{tsx,vue} : Use Ark UI components as foundation for accessibility

Applied to files:

  • packages/react/src/components/ui/pin-input.tsx
  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/input.tsx
  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
  • packages/react/src/components/ui/textarea.tsx
  • packages/react/src/components/ui/menu.tsx
  • packages/react/src/components/ui/dialog.tsx
📚 Learning: 2025-08-03T17:50:06.904Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-03T17:50:06.904Z
Learning: The project must use Ark UI as the component library

Applied to files:

  • packages/react/src/components/ui/pagination.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/menu.tsx
📚 Learning: 2025-08-03T17:49:16.881Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to components/**/*.tsx : Use React.forwardRef to forward refs in React components

Applied to files:

  • packages/react/src/components/ui/label.tsx
  • packages/react/src/components/ui/input.tsx
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are located in packages/react/src/components/ui/, using single-file architecture: one .tsx file per component

Applied to files:

  • packages/react/src/components/ui/sheet.tsx
  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/menu.tsx
📚 Learning: 2025-08-03T17:49:50.919Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/overview.mdc:0-0
Timestamp: 2025-08-03T17:49:50.919Z
Learning: Applies to packages/{react,vue}/src/components/ui/**/* : Ensure all UI components are accessible, leveraging Ark UI for accessibility features

Applied to files:

  • packages/react/src/components/ui/select.tsx
  • packages/react/src/components/ui/menu.tsx
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components use class-variance-authority (CVA) to manage style variants

Applied to files:

  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : Define component variants through CVA

Applied to files:

  • packages/react/src/components/ui/button.tsx
  • packages/react/src/components/ui/badge.tsx
🧬 Code graph analysis (10)
packages/react/src/components/ui/pin-input.tsx (1)
examples/next/components/ui/pin-input.tsx (2)
  • props (46-53)
  • props (88-92)
packages/react/src/components/ui/pagination.tsx (1)
examples/next/components/ui/pagination.tsx (4)
  • props (38-45)
  • props (73-81)
  • props (52-64)
  • props (108-117)
packages/react/src/components/ui/label.tsx (1)
examples/next/components/ui/label.tsx (1)
  • props (20-33)
packages/react/src/components/ui/sheet.tsx (1)
examples/next/components/ui/sheet.tsx (3)
  • props (98-105)
  • props (85-93)
  • props (77-83)
packages/react/src/components/ui/input.tsx (1)
examples/next/components/ui/input.tsx (1)
  • props (20-39)
packages/react/src/components/ui/button.tsx (1)
examples/next/components/ui/button.tsx (2)
  • ButtonProps (48-51)
  • props (54-63)
packages/react/src/components/ui/badge.tsx (1)
examples/next/components/ui/button.tsx (2)
  • ButtonProps (48-51)
  • props (54-63)
packages/react/src/components/ui/textarea.tsx (2)
examples/next/components/ui/textarea.tsx (1)
  • props (20-32)
examples/next/components/ui/label.tsx (1)
  • props (20-33)
packages/react/src/components/ui/menu.tsx (1)
examples/next/components/ui/menu.tsx (3)
  • props (151-163)
  • props (22-33)
  • props (172-185)
packages/react/src/components/ui/dialog.tsx (2)
examples/next/components/ui/dialog.tsx (5)
  • props (90-97)
  • props (23-32)
  • props (102-108)
  • props (39-59)
  • props (66-72)
examples/next/components/ui/sheet.tsx (1)
  • props (98-105)
🔇 Additional comments (9)
packages/react/src/components/ui/menu.tsx (1)

5-5: Approve: Verified no lingering polymorphic typings
Search confirms no PolymorphicProps or HTMLProps remain in packages/react/src/components/ui.

packages/react/src/components/ui/badge.tsx (1)

6-6: Typing migration to HTMLArkProps is clean and non-breaking.

CVA usage and runtime are untouched; props surface is simplified. Nice.

Also applies to: 36-37

packages/react/src/components/ui/pin-input.tsx (1)

5-5: Import update aligns with Ark factory usage.

No behavior change; OK.

packages/react/src/components/ui/button.tsx (1)

6-6: HTMLArkProps import looks correct for the refactor.

Matches Ark UI factory typing; no runtime impact.

packages/react/src/components/ui/select.tsx (2)

5-5: Factory import swap to HTMLArkProps is consistent with the refactor.


164-173: SelectSeparator migration to HTMLArkProps<"hr"> with ark.hr looks good.

Keeps anatomy attrs and styling; no behavior change.

packages/react/src/components/ui/sheet.tsx (3)

6-6: Importing HTMLArkProps from factory — aligned with repo-wide change.


101-110: SheetFooter refactor to ark.div + HTMLArkProps<"div"> LGTM.

Keeps anatomy attrs, preserves styling and ref type.


113-122: SheetHeader refactor to ark.div + HTMLArkProps<"div"> LGTM.

Consistent with Footer and other components in PR.

Comment on lines 44 to 46
export interface ButtonProps
extends PolymorphicProps,
HTMLProps<"button">,
extends HTMLArkProps<"button">,
VariantProps<typeof buttonVariants> {}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Props surface changed to non-polymorphic — verify external usage of as/asChild.

Dropping PolymorphicProps can break consumers relying on polymorphism.

Run to spot potential breakage across the repo:


🏁 Script executed:

#!/bin/bash
# Find Button usages that rely on polymorphism
rg -nP --type=tsx -C2 '\b<Button\b[^\n>]*\b(as|asChild)\b'
# Find lingering type imports to update in examples/docs
rg -nP --type=ts --type=tsx '\bPolymorphicProps\b|\bHTMLProps<"button"\b'

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Search for Button usages relying on polymorphic `as`/`asChild`
rg -nP '<Button\b[^>]*(\sas=|\sasChild=)' || true

# Search for PolymorphicProps references across codebase
rg -n 'PolymorphicProps' || true

# Search for HTMLProps<"button"> references
rg -n 'HTMLProps<"button">' || true

Length of output: 41784


Update examples/docs for removed polymorphic support on Button
No internal <Button as> or asChild usages detected. Examples in examples/next/components/ui (and JSON samples under apps/www/public/r/react) still import and extend PolymorphicProps & HTMLProps<"button">; they must be updated to use the new HTMLArkProps<"button"> signature and remove PolymorphicProps.

🤖 Prompt for AI Agents
In packages/react/src/components/ui/button.tsx around lines 44 to 46, the
ButtonProps signature now uses HTMLArkProps<"button"> instead of polymorphic
support; update all example and documentation usages accordingly: find any
imports and prop type extensions that reference PolymorphicProps and
HTMLProps<"button"> (notably under examples/next/components/ui and JSON samples
in apps/www/public/r/react) and replace them with the new HTMLArkProps<"button">
type, remove the PolymorphicProps import/usages, and adjust any type names and
imports to match the new signature so examples compile and reflect the
non-polymorphic Button API.

…lace HTMLProps/PolymorphicProps with HTMLArkProps from @ark-ui/react/factory\n- Update imports and types in Badge, Button, Dialog, Input, Label, Menu, Pagination, PinInput, Select, Sheet, Textarea
@github-actions
Copy link
Contributor

github-actions bot commented Sep 1, 2025

@iamdin iamdin merged commit 0fdfba7 into next Sep 1, 2025
3 of 4 checks passed
@iamdin iamdin deleted the refactor-html-ark-props branch September 1, 2025 12:06
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (8)
apps/www/public/r/react/dialog.json (1)

12-12: Add displayName for DialogFooter to match the PR objective.

Other parts already set displayName; align Footer for consistency.

 const DialogFooter = ({
   className,
   ...props
 }: React.HTMLAttributes<HTMLDivElement>) => (
   <div
     className={cn(
       "flex flex-col-reverse gap-3 sm:flex-row sm:justify-end",
       className
     )}
     {...props}
   />
 )
+DialogFooter.displayName = "DialogFooter"
apps/www/public/r/react/pin-input.json (1)

12-12: Consider marking MinusIcon as decorative.

Add aria-hidden="true" so it isn’t announced by screen readers.

apps/www/public/r/react/button.json (1)

12-12: Optionally align CVA usage with Badge for consistency.

Badge already merges className outside the variants call; Button should match.

apps/www/public/r/react/sheet.json (5)

12-12: Avoid double-applying backdrop attrs in SheetContent

Inside SheetContent you render the local SheetBackdrop and pass parts.backdrop.attrs again, but SheetBackdrop already spreads those attrs internally. Drop the extra spread to avoid redundant/duplicate props.

-    <SheetBackdrop {...parts.backdrop.attrs} />
+    <SheetBackdrop />

12-12: Consider simplifying side-based class branching

The side switch is readable but long. A small map reduces churn and helps future updates.

-        className={cn(
-          "fixed z-(--z-index) flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:duration-300 data-[state=open]:duration-500",
-          side === "right" &&
-            "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
-          side === "left" &&
-            "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
-          side === "top" &&
-            "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
-          side === "bottom" &&
-            "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
-          className
-        )}
+        className={cn(
+          "fixed z-(--z-index) flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:duration-300 data-[state=open]:duration-500",
+          {
+            right:
+              "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
+            left:
+              "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
+            top:
+              "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
+            bottom:
+              "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
+          }[side],
+          className,
+        )}

12-12: Minor: className passthrough doesn’t need cn()

For SheetTrigger and SheetCloseTrigger, className={cn(className)} is equivalent to className={className}. Keep cn() for places where you merge internal classes.

-    className={cn(className)}
+    className={className}

Applies to both SheetTrigger and SheetCloseTrigger.


12-12: Z-layering: ensure content reliably sits above backdrop

Both Backdrop and Content use the same z-(--z-index). DOM order generally makes Content appear above, but an explicit offset is safer across stacks/portals.

-  <SheetPrimitive.Backdrop
-    ... 
-    className={cn("... z-(--z-index) ...", className)}
+  <SheetPrimitive.Backdrop
+    ...
+    className={cn("... z-(--z-index) ...", className)}
   />
...
-      <SheetPrimitive.Content
+      <SheetPrimitive.Content
         ref={ref}
         {...parts.content.attrs}
-        className={cn("fixed z-(--z-index) ...", /* rest */)}
+        className={cn("fixed z-[calc(var(--z-index)+1)] ...", /* rest */)}

If calc isn’t desired, define two tokens (e.g., --z-index, --z-index-overlay) and use them respectively.


12-12: Docs: surface new API (side, header/footer parts)

Since this registry powers the docs site, add/update docs to cover:

  • side prop behaviors (top/right/bottom/left)
  • new header/footer parts and their attrs hooks
  • CloseTrigger presence inside Content

I can draft the MDX snippet and props table for apps/www if helpful.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 83b371c and 02e9f49.

📒 Files selected for processing (11)
  • apps/www/public/r/react/badge.json (1 hunks)
  • apps/www/public/r/react/button.json (1 hunks)
  • apps/www/public/r/react/dialog.json (1 hunks)
  • apps/www/public/r/react/input.json (1 hunks)
  • apps/www/public/r/react/label.json (1 hunks)
  • apps/www/public/r/react/menu.json (1 hunks)
  • apps/www/public/r/react/pagination.json (1 hunks)
  • apps/www/public/r/react/pin-input.json (1 hunks)
  • apps/www/public/r/react/select.json (1 hunks)
  • apps/www/public/r/react/sheet.json (1 hunks)
  • apps/www/public/r/react/textarea.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx,json,jsonc}

📄 CodeRabbit inference engine (.cursor/rules/overview.mdc)

Maintain code quality and style as configured in biome.jsonc

Files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
apps/www/**/*

📄 CodeRabbit inference engine (.cursor/rules/overview.mdc)

Document all components and features in the documentation website (apps/www/)

Files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
apps/www/**

📄 CodeRabbit inference engine (AGENTS.md)

Host the documentation site code in apps/www (Astro/MDX/Tailwind v4)

Files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are built on top of Ark UI components
Learnt from: CR
PR: shipbase/ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-30T18:56:37.501Z
Learning: Build components on top of Ark UI primitives
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to **/*.{tsx,vue} : Use Ark UI components as foundation for accessibility
Learnt from: CR
PR: shipbase/ui#0
File: AGENTS.md:0-0
Timestamp: 2025-08-30T18:58:30.749Z
Learning: Applies to packages/{react,vue}/src/**/*.{ts,tsx,vue} : Build components on top of Ark UI primitives in framework source code
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/overview.mdc:0-0
Timestamp: 2025-08-03T17:49:50.919Z
Learning: Applies to packages/{react,vue}/src/components/ui/**/* : Ensure all UI components are accessible, leveraging Ark UI for accessibility features
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-08-03T17:50:06.904Z
Learning: The project must use Ark UI as the component library
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are built on top of Ark UI components

Applied to files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
📚 Learning: 2025-08-30T18:58:30.749Z
Learnt from: CR
PR: shipbase/ui#0
File: AGENTS.md:0-0
Timestamp: 2025-08-30T18:58:30.749Z
Learning: Applies to packages/{react,vue}/src/**/*.{ts,tsx,vue} : Build components on top of Ark UI primitives in framework source code

Applied to files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components support forwardRef and complete TypeScript types

Applied to files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/dialog.json
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are located in packages/react/src/components/ui/, using single-file architecture: one .tsx file per component

Applied to files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
📚 Learning: 2025-08-03T17:49:16.881Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to **/*.{tsx,vue} : Use Ark UI components as foundation for accessibility

Applied to files:

  • apps/www/public/r/react/pagination.json
  • apps/www/public/r/react/textarea.json
  • apps/www/public/r/react/input.json
  • apps/www/public/r/react/pin-input.json
  • apps/www/public/r/react/button.json
  • apps/www/public/r/react/badge.json
  • apps/www/public/r/react/label.json
  • apps/www/public/r/react/menu.json
  • apps/www/public/r/react/sheet.json
  • apps/www/public/r/react/select.json
  • apps/www/public/r/react/dialog.json
📚 Learning: 2025-08-03T17:49:16.881Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to components/**/*.tsx : React component files must use kebab-case naming (e.g. button.tsx, toggle-group.tsx)

Applied to files:

  • apps/www/public/r/react/button.json
📚 Learning: 2025-08-03T17:49:32.389Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/vue/src/components/ui/*/*.vue : Vue components are located in packages/vue/src/components/ui/, using directory architecture: one directory per component with main component file Button.vue

Applied to files:

  • apps/www/public/r/react/button.json
📚 Learning: 2025-08-03T17:49:50.919Z
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/overview.mdc:0-0
Timestamp: 2025-08-03T17:49:50.919Z
Learning: Applies to packages/{react,vue}/src/components/ui/**/* : Ensure all UI components are accessible, leveraging Ark UI for accessibility features

Applied to files:

  • apps/www/public/r/react/menu.json
🧬 Code graph analysis (9)
apps/www/public/r/react/textarea.json (2)
packages/react/src/components/ui/textarea.tsx (1)
  • props (20-32)
examples/next/components/ui/textarea.tsx (1)
  • props (20-32)
apps/www/public/r/react/input.json (1)
packages/react/src/components/ui/input.tsx (1)
  • props (20-39)
apps/www/public/r/react/pin-input.json (2)
packages/react/src/components/ui/input.tsx (1)
  • props (20-39)
examples/next/components/ui/select.tsx (1)
  • props (161-168)
apps/www/public/r/react/button.json (3)
packages/react/src/components/ui/button.tsx (2)
  • ButtonProps (48-51)
  • props (54-63)
examples/next/components/ui/button.tsx (2)
  • ButtonProps (48-51)
  • props (54-63)
apps/www/src/components/copy-button.tsx (1)
  • CopyButtonProps (6-9)
apps/www/public/r/react/badge.json (2)
examples/next/components/ui/button.tsx (1)
  • ButtonProps (48-51)
packages/react/src/components/ui/button.tsx (1)
  • ButtonProps (48-51)
apps/www/public/r/react/menu.json (2)
examples/next/components/ui/menu.tsx (4)
  • props (151-163)
  • props (22-33)
  • props (172-185)
  • props (59-70)
packages/react/src/components/ui/menu.tsx (6)
  • props (59-70)
  • props (151-163)
  • props (22-33)
  • props (140-146)
  • props (81-91)
  • props (38-54)
apps/www/public/r/react/sheet.json (1)
examples/next/app/(components)/sheet/page.tsx (1)
  • Component (15-47)
apps/www/public/r/react/select.json (2)
examples/next/components/ui/select.tsx (7)
  • props (161-168)
  • props (45-60)
  • props (67-76)
  • props (173-182)
  • props (31-40)
  • props (145-154)
  • props (81-85)
packages/react/src/components/ui/select.tsx (3)
  • props (161-168)
  • props (173-182)
  • props (45-60)
apps/www/public/r/react/dialog.json (2)
examples/next/components/ui/dialog.tsx (5)
  • props (90-97)
  • props (23-32)
  • props (102-108)
  • props (39-59)
  • props (66-72)
packages/react/src/components/ui/dialog.tsx (2)
  • props (90-97)
  • props (102-108)
🔇 Additional comments (9)
apps/www/public/r/react/menu.json (1)

12-12: HTMLArkProps migration for Menu looks correct.

  • Correct import of HTMLArkProps/ark and proper use in MenuShortcut.
  • All forwardRef components define displayName.
apps/www/public/r/react/select.json (1)

12-12: SelectSeparator typing updated correctly to HTMLArkProps.

Runtime remains unchanged and displayName is set. Looks good.

apps/www/public/r/react/textarea.json (1)

11-11: Textarea: clean HTMLArkProps refactor.

Type and anatomy usage look correct; displayName present.

apps/www/public/r/react/badge.json (1)

12-12: Badge props refactor looks solid; runtime unchanged.

ForwardRef + HTMLArkProps usage is correct, parts.attrs applied, and displayName set. No issues.

apps/www/public/r/react/pin-input.json (2)

12-12: Replace intrinsic React.ElementRef<"div"> generics with appropriate component refs
Occurrences to update:

  • packages/react/src/components/ui/pin-input.tsx:42, 87
  • examples/next/components/ui/pin-input.tsx:44, 86

12-12: Incorrect ref generic for intrinsic div; use HTMLDivElement.

React.ElementRef<"div"> is invalid for intrinsic elements and will fail typechecking for consumers. Use HTMLDivElement for both Group and Separator.

Apply this diff inside the content string:

-const PinInputGroup = React.forwardRef<
-  React.ElementRef<"div">,
-  HTMLArkProps<"div">
+const PinInputGroup = React.forwardRef<
+  HTMLDivElement,
+  HTMLArkProps<"div">
 >(({ className, ...props }, ref) => (
   <ark.div
     ref={ref}
     {...parts.group.attrs}
     className={cn("flex items-center", className)}
     {...props}
   />
 ))
 
-const PinInputSeparator = React.forwardRef<
-  React.ElementRef<"div">,
-  HTMLArkProps<"div">
+const PinInputSeparator = React.forwardRef<
+  HTMLDivElement,
+  HTMLArkProps<"div">
 >((props, ref) => (
   <ark.div ref={ref} {...parts.separator.attrs} {...props}>
-    <MinusIcon />
+    <MinusIcon aria-hidden="true" />
   </ark.div>
 ))

Note: added aria-hidden on the decorative MinusIcon.

⛔ Skipped due to learnings
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to components/**/*.tsx : Use React.forwardRef to forward refs in React components
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components support forwardRef and complete TypeScript types
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/component-development.mdc:0-0
Timestamp: 2025-08-03T17:49:32.389Z
Learning: Applies to packages/react/src/components/ui/*.tsx : React components are built on top of Ark UI components
Learnt from: CR
PR: shipbase/ui#0
File: AGENTS.md:0-0
Timestamp: 2025-08-30T18:58:30.749Z
Learning: Applies to packages/{react,vue}/src/**/*.{ts,tsx,vue} : Build components on top of Ark UI primitives in framework source code
Learnt from: CR
PR: shipbase/ui#0
File: .cursor/rules/code-standards.mdc:0-0
Timestamp: 2025-08-03T17:49:16.881Z
Learning: Applies to **/*.{tsx,vue} : Use Ark UI components as foundation for accessibility
apps/www/public/r/react/input.json (1)

11-11: Input migration to HTMLArkProps looks correct.

Good use of parts.attrs, forwardRef typing, and displayName. No further action.

apps/www/public/r/react/label.json (1)

11-11: Label migration LGTM.

Props, forwardRef target, parts.attrs, and displayName are all correct.

apps/www/public/r/react/sheet.json (1)

12-12: Display names and Ark HTMLArkProps migration look solid

All forwardRef components set displayName, and header/footer correctly adopt HTMLArkProps<"div"> with ark.div wrappers.

{
"path": "./src/components/ui/button.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { createAnatomy } from \"@ark-ui/react/anatomy\"\nimport {\n type HTMLProps,\n type PolymorphicProps,\n ark,\n} from \"@ark-ui/react/factory\"\nimport { type VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst anatomy = createAnatomy(\"button\").parts(\"root\")\nconst parts = anatomy.build()\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\",\n outline:\n \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends PolymorphicProps,\n HTMLProps<\"button\">,\n VariantProps<typeof buttonVariants> {}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => {\n return (\n <ark.button\n ref={ref}\n {...parts.root.attrs}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { createAnatomy } from \"@ark-ui/react/anatomy\"\nimport { type HTMLArkProps, ark } from \"@ark-ui/react/factory\"\nimport { type VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst anatomy = createAnatomy(\"button\").parts(\"root\")\nconst parts = anatomy.build()\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\",\n outline:\n \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends HTMLArkProps<\"button\">,\n VariantProps<typeof buttonVariants> {}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => {\n return (\n <ark.button\n ref={ref}\n {...parts.root.attrs}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

className merging bug with CVA; user classes are dropped.

className={cn(buttonVariants({ variant, size, className }))} passes className into CVA instead of merging it. This likely ignores consumer classes. Merge via cn instead.

Apply:

-        className={cn(buttonVariants({ variant, size, className }))}
+        className={cn(buttonVariants({ variant, size }), className)}
📝 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
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { createAnatomy } from \"@ark-ui/react/anatomy\"\nimport { type HTMLArkProps, ark } from \"@ark-ui/react/factory\"\nimport { type VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst anatomy = createAnatomy(\"button\").parts(\"root\")\nconst parts = anatomy.build()\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\",\n outline:\n \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends HTMLArkProps<\"button\">,\n VariantProps<typeof buttonVariants> {}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => {\n return (\n <ark.button\n ref={ref}\n {...parts.root.attrs}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n",
<ark.button
ref={ref}
{...parts.root.attrs}
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
🤖 Prompt for AI Agents
In apps/www/public/r/react/button.json around line 12, the Button component
incorrectly passes className into the CVA call (buttonVariants({ variant, size,
className })), which causes consumer classes to be ignored; change the render to
call buttonVariants only with the variant and size, then merge the result with
the incoming className via cn (e.g. cn(buttonVariants({ variant, size }),
className)) so consumer classes are preserved.

{
"path": "./src/components/ui/pagination.tsx",
"content": "\"use client\"\n\nimport {\n type HTMLProps,\n type PolymorphicProps,\n ark,\n} from \"@ark-ui/react/factory\"\nimport {\n Pagination as PaginationPrimitive,\n paginationAnatomy,\n} from \"@ark-ui/react/pagination\"\nimport type { VariantProps } from \"class-variance-authority\"\nimport { MoreHorizontal } from \"lucide-react\"\nimport * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\n\nconst parts = paginationAnatomy.extendWith(\"content\").build()\n\nconst Pagination = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Root>,\n Omit<PaginationPrimitive.RootProps, \"type\">\n>(({ className, ...props }, ref) => (\n <PaginationPrimitive.Root\n ref={ref}\n className={cn(\n \"mx-auto flex w-full flex-row items-center justify-center gap-1\",\n className\n )}\n {...props}\n />\n))\nPagination.displayName = \"Pagination\"\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n PolymorphicProps & HTMLProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ark.ul\n ref={ref}\n {...parts.content.attrs}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationContext = PaginationPrimitive.Context\n\nconst PaginationEllipsis = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Ellipsis>,\n PaginationPrimitive.EllipsisProps\n>(({ className, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.Ellipsis\n ref={ref}\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </PaginationPrimitive.Ellipsis>\n </ark.li>\n))\nPaginationEllipsis.displayName = \"PaginationEllipsis\"\n\nexport interface PaginationItemProps\n extends PaginationPrimitive.ItemProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationItem = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Item>,\n PaginationItemProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.Item\n ref={ref}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationItem.displayName = \"PaginationItem\"\n\nexport interface PaginationNextTriggerProps\n extends PaginationPrimitive.NextTriggerProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationNextTrigger = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.NextTrigger>,\n PaginationNextTriggerProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.NextTrigger\n ref={ref}\n aria-label=\"Go to next page\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationNextTrigger.displayName = \"PaginationNextTrigger\"\n\nexport interface PaginationPrevTriggerProps\n extends PaginationPrimitive.PrevTriggerProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationPrevTrigger = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.PrevTrigger>,\n PaginationPrevTriggerProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.PrevTrigger\n ref={ref}\n aria-label=\"Go to previous page\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationPrevTrigger.displayName = \"PaginationPrevTrigger\"\n\nconst PaginationRootProvider = PaginationPrimitive.RootProvider\n\nexport {\n Pagination,\n PaginationContent,\n PaginationContext,\n PaginationEllipsis,\n PaginationItem,\n PaginationNextTrigger,\n PaginationPrevTrigger,\n PaginationRootProvider,\n}\n\nexport { usePagination } from \"@ark-ui/react/pagination\"\n",
"content": "\"use client\"\n\nimport { type HTMLArkProps, ark } from \"@ark-ui/react/factory\"\nimport {\n Pagination as PaginationPrimitive,\n paginationAnatomy,\n} from \"@ark-ui/react/pagination\"\nimport type { VariantProps } from \"class-variance-authority\"\nimport { MoreHorizontal } from \"lucide-react\"\nimport * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\n\nconst parts = paginationAnatomy.extendWith(\"content\").build()\n\nconst Pagination = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Root>,\n Omit<PaginationPrimitive.RootProps, \"type\">\n>(({ className, ...props }, ref) => (\n <PaginationPrimitive.Root\n ref={ref}\n className={cn(\n \"mx-auto flex w-full flex-row items-center justify-center gap-1\",\n className\n )}\n {...props}\n />\n))\nPagination.displayName = \"Pagination\"\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n HTMLArkProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ark.ul\n ref={ref}\n {...parts.content.attrs}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationContext = PaginationPrimitive.Context\n\nconst PaginationEllipsis = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Ellipsis>,\n PaginationPrimitive.EllipsisProps\n>(({ className, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.Ellipsis\n ref={ref}\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </PaginationPrimitive.Ellipsis>\n </ark.li>\n))\nPaginationEllipsis.displayName = \"PaginationEllipsis\"\n\nexport interface PaginationItemProps\n extends PaginationPrimitive.ItemProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationItem = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Item>,\n PaginationItemProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.Item\n ref={ref}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationItem.displayName = \"PaginationItem\"\n\nexport interface PaginationNextTriggerProps\n extends PaginationPrimitive.NextTriggerProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationNextTrigger = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.NextTrigger>,\n PaginationNextTriggerProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.NextTrigger\n ref={ref}\n aria-label=\"Go to next page\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationNextTrigger.displayName = \"PaginationNextTrigger\"\n\nexport interface PaginationPrevTriggerProps\n extends PaginationPrimitive.PrevTriggerProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationPrevTrigger = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.PrevTrigger>,\n PaginationPrevTriggerProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.PrevTrigger\n ref={ref}\n aria-label=\"Go to previous page\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationPrevTrigger.displayName = \"PaginationPrevTrigger\"\n\nconst PaginationRootProvider = PaginationPrimitive.RootProvider\n\nexport {\n Pagination,\n PaginationContent,\n PaginationContext,\n PaginationEllipsis,\n PaginationItem,\n PaginationNextTrigger,\n PaginationPrevTrigger,\n PaginationRootProvider,\n}\n\nexport { usePagination } from \"@ark-ui/react/pagination\"\n",
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix a11y: Ellipsis has aria-hidden but also an sr-only label.

With aria-hidden on the parent, the “More pages” label won’t be announced. Remove aria-hidden so the label is usable.

-  <ark.li>
-    <PaginationPrimitive.Ellipsis
-      ref={ref}
-      aria-hidden
-      className={cn("flex h-9 w-9 items-center justify-center", className)}
-      {...props}
-    >
+  <ark.li>
+    <PaginationPrimitive.Ellipsis
+      ref={ref}
+      className={cn("flex h-9 w-9 items-center justify-center", className)}
+      {...props}
+    >
       <MoreHorizontal className="h-4 w-4" />
       <span className="sr-only">More pages</span>
     </PaginationPrimitive.Ellipsis>
   </ark.li>
📝 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
"content": "\"use client\"\n\nimport { type HTMLArkProps, ark } from \"@ark-ui/react/factory\"\nimport {\n Pagination as PaginationPrimitive,\n paginationAnatomy,\n} from \"@ark-ui/react/pagination\"\nimport type { VariantProps } from \"class-variance-authority\"\nimport { MoreHorizontal } from \"lucide-react\"\nimport * as React from \"react\"\n\nimport { buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\n\nconst parts = paginationAnatomy.extendWith(\"content\").build()\n\nconst Pagination = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Root>,\n Omit<PaginationPrimitive.RootProps, \"type\">\n>(({ className, ...props }, ref) => (\n <PaginationPrimitive.Root\n ref={ref}\n className={cn(\n \"mx-auto flex w-full flex-row items-center justify-center gap-1\",\n className\n )}\n {...props}\n />\n))\nPagination.displayName = \"Pagination\"\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n HTMLArkProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ark.ul\n ref={ref}\n {...parts.content.attrs}\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n))\nPaginationContent.displayName = \"PaginationContent\"\n\nconst PaginationContext = PaginationPrimitive.Context\n\nconst PaginationEllipsis = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Ellipsis>,\n PaginationPrimitive.EllipsisProps\n>(({ className, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.Ellipsis\n ref={ref}\n aria-hidden\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">More pages</span>\n </PaginationPrimitive.Ellipsis>\n </ark.li>\n))\nPaginationEllipsis.displayName = \"PaginationEllipsis\"\n\nexport interface PaginationItemProps\n extends PaginationPrimitive.ItemProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationItem = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.Item>,\n PaginationItemProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.Item\n ref={ref}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationItem.displayName = \"PaginationItem\"\n\nexport interface PaginationNextTriggerProps\n extends PaginationPrimitive.NextTriggerProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationNextTrigger = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.NextTrigger>,\n PaginationNextTriggerProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.NextTrigger\n ref={ref}\n aria-label=\"Go to next page\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationNextTrigger.displayName = \"PaginationNextTrigger\"\n\nexport interface PaginationPrevTriggerProps\n extends PaginationPrimitive.PrevTriggerProps,\n VariantProps<typeof buttonVariants> {}\n\nconst PaginationPrevTrigger = React.forwardRef<\n React.ElementRef<typeof PaginationPrimitive.PrevTrigger>,\n PaginationPrevTriggerProps\n>(({ className, variant = \"outline\", size, ...props }, ref) => (\n <ark.li>\n <PaginationPrimitive.PrevTrigger\n ref={ref}\n aria-label=\"Go to previous page\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n </ark.li>\n))\nPaginationPrevTrigger.displayName = \"PaginationPrevTrigger\"\n\nconst PaginationRootProvider = PaginationPrimitive.RootProvider\n\nexport {\n Pagination,\n PaginationContent,\n PaginationContext,\n PaginationEllipsis,\n PaginationItem,\n PaginationNextTrigger,\n PaginationPrevTrigger,\n PaginationRootProvider,\n}\n\nexport { usePagination } from \"@ark-ui/react/pagination\"\n",
const PaginationEllipsis = React.forwardRef<
React.ElementRef<typeof PaginationPrimitive.Ellipsis>,
PaginationPrimitive.EllipsisProps
>(({ className, ...props }, ref) => (
<ark.li>
<PaginationPrimitive.Ellipsis
ref={ref}
className={cn("flex h-9 w-9 items-center justify-center", className)}
{...props}
>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More pages</span>
</PaginationPrimitive.Ellipsis>
</ark.li>
))
PaginationEllipsis.displayName = "PaginationEllipsis"
🤖 Prompt for AI Agents
In apps/www/public/r/react/pagination.json around line 16, the
PaginationPrimitive.Ellipsis element has aria-hidden while also containing an
sr-only “More pages” label; remove the aria-hidden attribute from the Ellipsis
component so the assistive text is announced, and if the MoreHorizontal icon
should be ignored by screen readers, instead add aria-hidden to the icon element
(or role="img" aria-hidden="true") so the visible SVG is hidden but the sr-only
label remains accessible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants