Skip to content

Conversation

@TheOrcDev
Copy link
Owner

@TheOrcDev TheOrcDev commented Aug 16, 2025

Summary by CodeRabbit

  • New Features

    • Added an 8‑bit Chapter Intro hero banner with configurable title, subtitle, background, alignment, height, and overlay.
    • Introduced retro-styled Card UI and theme styling powering the banner.
    • Integrated the Chapter Intro into the gaming page and the component showcase for immediate use.
  • Chores

    • Published the Chapter Intro and related assets to the component registry for easy adoption.

@vercel
Copy link

vercel bot commented Aug 16, 2025

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

Project Deployment Preview Comments Updated (UTC)
8bitcn-ui Ready Ready Preview Comment Aug 16, 2025 10:37pm

@coderabbitai
Copy link

coderabbitai bot commented Aug 16, 2025

Walkthrough

Introduces a new 8-bit ChapterIntro UI component and integrates it into GamingBlocks and ComponentShowcase. Adds registry entries for the component and retro assets. Updates a registry typing for DifficultySelect to avoid onChange conflict. No existing exported signatures changed aside from the DifficultySelectProps type tweak.

Changes

Cohort / File(s) Summary
New 8-bit ChapterIntro component and primitives
components/ui/8bit/blocks/chapter-intro.tsx, components/ui/8bit/card.tsx, components/ui/8bit/styles/retro.css
Adds ChapterIntro hero component with configurable title/subtitle, alignment, height, background, and darken overlay. Introduces retro-styled Card primitives and retro CSS stylesheet used by ChapterIntro.
Integrations in app pages
app/blocks/gaming/gaming.tsx, components/examples/component-showcase.tsx
Imports and renders ChapterIntro: a new top container in GamingBlocks; replaces a prior Card/LoginForm area in ComponentShowcase with ChapterIntro.
Registry additions
registry.json, public/r/8bit-chapter-intro.json
Registers “8bit-chapter-intro” component with dependencies and file mappings (chapter-intro.tsx, card.tsx, retro.css).
Type adjustment in registry descriptor
public/r/8bit-difficulty-select.json
Updates DifficultySelectProps to extend Omit<HTMLAttributes, "onChange">, preventing prop name collision.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Page as GamingBlocks/Showcase
  participant ChapterIntro
  participant Card
  User->>Page: Navigate / render
  Page->>ChapterIntro: Render with props (title, subtitle, background, align, height, darken)
  ChapterIntro->>Card: Compose Card/CardContent
  ChapterIntro->>ChapterIntro: Apply background + darken + letterbox
  Card-->>Page: Rendered hero block
  Page-->>User: UI displayed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

In pixel dusk, I hop and cheer,
A chapter dawns, the path is clear.
Letterbox skies and ember light,
Cards in retro, bold and bright.
Level one whispers, “Onward, go!”
I twitch my nose—adventure’s show. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/chapter-intro

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 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.

@TheOrcDev TheOrcDev merged commit b7ea749 into main Aug 16, 2025
2 of 3 checks passed
@TheOrcDev TheOrcDev deleted the feat/chapter-intro branch August 16, 2025 22:38
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 (4)
public/r/8bit-chapter-intro.json (4)

12-16: Clamp the darken overlay to [0,1] to avoid unexpected visuals

If consumers pass values outside [0,1], the overlay can fully disappear or over-darken. Clamp before applying.

Apply this diff within chapter-intro.tsx:

 export default function ChapterIntro({
   className,
   title,
   subtitle,
   backgroundSrc = "/placeholder.svg",
   align = "center",
   height = "md",
   darken = 0.5,
   ...props
 }: ChapterIntroProps) {
+  const overlayOpacity = Math.max(0, Math.min(1, darken ?? 0));
@@
           {/* Darken/gradient overlay for readability */}
           <div
             className="absolute inset-0 bg-background/60 mix-blend-multiply"
-            style={{ opacity: darken }}
+            style={{ opacity: overlayOpacity }}
             aria-hidden="true"
           />

Optional: if this is a Next.js app, consider using next/image for better performance and domain control.


18-22: Avoid @import’ing Google Fonts in CSS; prefer next/font or self-hosted fonts

Remote @import calls cause render-blocking waterfalls and may be blocked by CSP. Prefer loading Press Start 2P via next/font/google (or self-hosting) and scoping the class accordingly.


24-28: Consider actually using cardVariants for class composition

You define cardVariants but don’t use it to compute classes. Using it would centralize variant logic and defaulting.

Example tweak:

- className={cn(
-   "rounded-none border-0 !w-full",
-   font !== "normal" && "retro",
-   className
- )}
+ className={cn("rounded-none border-0 !w-full", cardVariants({ font }), className)}

24-28: Passing the same className to both wrapper div and inner Card may confuse consumers

You apply the consumer’s className to both the outer wrapper and ShadcnCard. If that’s not intentional, consider splitting props (e.g., wrapperClassName vs className) or only applying to the root.

📜 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 4c6ae20 and 1c64e68.

⛔ Files ignored due to path filters (1)
  • public/images/fiery-skeletons.png is excluded by !**/*.png
📒 Files selected for processing (6)
  • app/blocks/gaming/gaming.tsx (2 hunks)
  • components/examples/component-showcase.tsx (2 hunks)
  • components/ui/8bit/blocks/chapter-intro.tsx (1 hunks)
  • public/r/8bit-chapter-intro.json (1 hunks)
  • public/r/8bit-difficulty-select.json (1 hunks)
  • registry.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
components/examples/component-showcase.tsx (2)
components/ui/8bit/blocks/chapter-intro.tsx (1)
  • ChapterIntro (14-89)
components/ui/card.tsx (1)
  • CardDescription (41-49)
registry.json (2)
components/ui/8bit/card.tsx (3)
  • CardDescription (84-93)
  • CardTitle (73-82)
  • CardContent (106-115)
components/ui/8bit/menubar.tsx (3)
  • props (58-79)
  • props (139-148)
  • props (182-192)
app/blocks/gaming/gaming.tsx (4)
app/docs/components/copy-command-button.tsx (1)
  • CopyCommandButton (13-31)
app/docs/components/open-in-v0-button.tsx (1)
  • OpenInV0Button (5-39)
components/ui/8bit/blocks/chapter-intro.tsx (1)
  • ChapterIntro (14-89)
app/blocks/gaming/page.tsx (1)
  • GamingBlocksPage (13-29)
public/r/8bit-difficulty-select.json (7)
components/ui/8bit/select.tsx (4)
  • BitSelectProps (33-37)
  • BitSelectValueProps (49-53)
  • BitSelectContentProps (98-102)
  • Select (39-41)
components/ui/8bit/alert.tsx (1)
  • BitAlertProps (28-30)
components/ui/8bit/dialog.tsx (1)
  • BitDialogProps (30-32)
components/ui/8bit/mana-bar.tsx (1)
  • ManaBarProps (3-8)
components/ui/8bit/toggle.tsx (1)
  • BitToggleProps (38-40)
components/ui/8bit/card.tsx (1)
  • BitCardProps (29-33)
components/ui/8bit/health-bar.tsx (1)
  • ManaBarProps (3-8)
public/r/8bit-chapter-intro.json (1)
components/ui/8bit/card.tsx (8)
  • CardDescription (84-93)
  • CardTitle (73-82)
  • CardContent (106-115)
  • Card (35-60)
  • CardAction (95-104)
  • BitCardProps (29-33)
  • CardHeader (62-71)
  • CardFooter (117-127)
🔇 Additional comments (10)
public/r/8bit-difficulty-select.json (1)

14-14: LGTM! Type refinement resolves onChange prop conflict.

The updated DifficultySelectProps interface properly extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> to avoid TypeScript conflicts between the native HTML onChange event and the component's custom onChange prop. This follows the established pattern seen in other 8-bit components and maintains type safety.

app/blocks/gaming/gaming.tsx (2)

1-1: LGTM! Clean import addition for the new ChapterIntro component.

The import follows the established pattern for other 8-bit block components in this file.


17-41: Excellent integration of the ChapterIntro component.

The new ChapterIntro block is well-structured and consistent with the existing gaming blocks pattern. The component usage is configured appropriately with meaningful props (title, subtitle, background image, alignment, and darkening effect). The layout matches the established pattern with proper header, action buttons, and responsive design.

components/examples/component-showcase.tsx (2)

37-37: LGTM! Import follows established patterns.

The ChapterIntro import is properly placed with other 8-bit block components and uses a relative path consistent with the file structure.


113-121: Well-integrated ChapterIntro showcase example.

The ChapterIntro component is properly integrated into the showcase with appropriate styling and props. The usage demonstrates the component's capabilities with a gaming-themed example that aligns with the 8-bit aesthetic. The responsive width classes and text styling are well-considered.

registry.json (1)

6-29: Well-structured registry entry for the new ChapterIntro component.

The registry entry follows the established pattern and correctly:

  • Declares dependency on the "card" component
  • Includes all necessary files (component, styling, and card dependency)
  • Provides clear title and description
  • Uses consistent file structure and target paths

The three-file approach (main component, retro styling, and card component) is appropriate for the component's composition.

components/ui/8bit/blocks/chapter-intro.tsx (3)

5-12: Well-designed interface with comprehensive prop options.

The ChapterIntroProps interface provides excellent flexibility with thoughtful defaults. The prop types are appropriate:

  • Required title for primary content
  • Optional subtitle for additional context
  • Configurable backgroundSrc, align, height, and darken with sensible defaults
  • Proper extension of React.ComponentProps<"div"> for standard HTML div attributes

The darken prop using a number (0-1 range implied) is intuitive for opacity control.


24-36: Clean implementation of responsive design utilities.

The computed classes for height and alignment are well-structured:

  • Height classes provide good responsive breakpoints (sm/md/lg with mobile-first approach)
  • Alignment classes properly map to flexbox utilities for text positioning
  • Ternary operators are readable and follow consistent patterns

The responsive min-heights scale appropriately across device sizes.


38-88: Excellent cinematic component implementation.

The ChapterIntro component is well-architected with:

  • Proper semantic structure using Card/CardContent composition
  • Layered design with background image, overlay, letterbox bars, and content
  • Pixelated image rendering for authentic 8-bit aesthetics
  • Accessible implementation with proper ARIA labels and alt text
  • Good responsive design with appropriate padding and text sizes
  • Effective use of drop shadows for text legibility over backgrounds
  • Clean separation of concerns between visual layers

The darken overlay implementation using mix-blend-multiply with configurable opacity is sophisticated and provides good contrast control.

public/r/8bit-chapter-intro.json (1)

1-9: Registry metadata looks consistent and dependency is appropriate

Schema, item type, and dependency on the base "card" look correct for composing the 8-bit Card wrappers over shadcn/ui Card.

Comment on lines +24 to +28
"path": "components/ui/8bit/card.tsx",
"content": "import { type VariantProps, cva } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport {\n Card as ShadcnCard,\n CardAction as ShadcnCardAction,\n CardContent as ShadcnCardContent,\n CardDescription as ShadcnCardDescription,\n CardFooter as ShadcnCardFooter,\n CardHeader as ShadcnCardHeader,\n CardTitle as ShadcnCardTitle,\n} from \"@/components/ui/card\";\n\nimport \"./styles/retro.css\";\n\nexport const cardVariants = cva(\"\", {\n variants: {\n font: {\n normal: \"\",\n retro: \"retro\",\n },\n },\n defaultVariants: {\n font: \"retro\",\n },\n});\n\nexport interface BitCardProps\n extends React.ComponentProps<\"div\">,\n VariantProps<typeof cardVariants> {\n asChild?: boolean;\n}\n\nfunction Card({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <div\n className={cn(\n \"relative border-y-6 border-foreground dark:border-ring !p-0\",\n className\n )}\n >\n <ShadcnCard\n {...props}\n className={cn(\n \"rounded-none border-0 !w-full\",\n font !== \"normal\" && \"retro\",\n className\n )}\n />\n\n <div\n className=\"absolute inset-0 border-x-6 -mx-1.5 border-foreground dark:border-ring pointer-events-none\"\n aria-hidden=\"true\"\n />\n </div>\n );\n}\n\nfunction CardHeader({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardHeader\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardTitle\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardDescription\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardAction\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardContent\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardFooter({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardFooter\n data-slot=\"card-footer\"\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n};\n",
"type": "registry:component",
"target": "components/ui/8bit/card.tsx"
}
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

Confirm that base Card actually exports CardAction

Shadcn’s default Card API usually does not include CardAction; if your local components/ui/card adds it, all good—otherwise this will break imports.

Run this script to verify the export:


🏁 Script executed:

#!/bin/bash
# Verify whether components/ui/card exports CardAction
fd -t f -a 'card.*\.(t|j)sx?$' components | xargs -I{} rg -n -C2 -P 'export\s+\{[^}]*CardAction[^}]*\}' {}

Length of output: 112


🏁 Script executed:

#!/bin/bash
# Locate card module(s) under components/ui and check for CardAction exports
echo "=== Listing all card-related files in components/ui ==="
fd -HI 'card.*\.(ts|tsx)' components/ui

echo -e "\n=== Searching each file for CardAction export or definition ==="
fd -HI 'card.*\.(ts|tsx)' components/ui | while read -r file; do
  echo -e "\n---> $file"
  rg -nC2 'export\s+\{[^}]*CardAction[^}]*\}' "$file"
  rg -nC2 'export\s+(function|const)\s+CardAction' "$file"
done

Length of output: 1480


Export or Remove CardAction to Prevent Broken Imports

The file components/ui/card.tsx does not export CardAction, so importing CardAction as ShadcnCardAction in public/r/8bit-chapter-intro.json (targeting components/ui/8bit/card.tsx) will break at runtime.

• components/ui/card.tsx – add CardAction to the named exports (or define and export it)
• components/ui/8bit/card.tsx – if you don’t intend to extend CardAction, remove its import and usages instead

🤖 Prompt for AI Agents
In public/r/8bit-chapter-intro.json around lines 24 to 28: the 8bit variant
imports ShadcnCardAction from components/ui/card.tsx but that file does not
export CardAction, causing runtime breakage; either add and export CardAction
from components/ui/card.tsx (so the 8bit wrapper can extend it) or remove the
import and any CardAction component/usage from components/ui/8bit/card.tsx and
replace with a supported exported component (e.g., use a plain div or
ShadcnCard’s existing exported slots); update imports accordingly and run a
quick build to verify no unresolved imports remain.

🛠️ Refactor suggestion

Do not forward variant props (e.g., font) to DOM; destructure them out before spreading

Currently each wrapper passes {...props} down to shadcn Card primitives; this leaks "font" onto DOM nodes, creating invalid attributes and potential hydration/warning issues. Destructure and pass the rest.

Apply this diff within card.tsx:

-function Card({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function Card({ className, font, ...rest }: BitCardProps) {
@@
-      <ShadcnCard
-        {...props}
+      <ShadcnCard
+        {...rest}
         className={cn(
           "rounded-none border-0 !w-full",
           font !== "normal" && "retro",
           className
         )}
       />
@@
-function CardHeader({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function CardHeader({ className, font, ...rest }: BitCardProps) {
@@
-    <ShadcnCardHeader
-      className={cn(font !== "normal" && "retro", className)}
-      {...props}
-    />
+    <ShadcnCardHeader
+      className={cn(font !== "normal" && "retro", className)}
+      {...rest}
+    />
@@
-function CardTitle({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function CardTitle({ className, font, ...rest }: BitCardProps) {
@@
-    <ShadcnCardTitle
-      className={cn(font !== "normal" && "retro", className)}
-      {...props}
-    />
+    <ShadcnCardTitle
+      className={cn(font !== "normal" && "retro", className)}
+      {...rest}
+    />
@@
-function CardDescription({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function CardDescription({ className, font, ...rest }: BitCardProps) {
@@
-    <ShadcnCardDescription
-      className={cn(font !== "normal" && "retro", className)}
-      {...props}
-    />
+    <ShadcnCardDescription
+      className={cn(font !== "normal" && "retro", className)}
+      {...rest}
+    />
@@
-function CardAction({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function CardAction({ className, font, ...rest }: BitCardProps) {
@@
-    <ShadcnCardAction
-      className={cn(font !== "normal" && "retro", className)}
-      {...props}
-    />
+    <ShadcnCardAction
+      className={cn(font !== "normal" && "retro", className)}
+      {...rest}
+    />
@@
-function CardContent({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function CardContent({ className, font, ...rest }: BitCardProps) {
@@
-    <ShadcnCardContent
-      className={cn(font !== "normal" && "retro", className)}
-      {...props}
-    />
+    <ShadcnCardContent
+      className={cn(font !== "normal" && "retro", className)}
+      {...rest}
+    />
@@
-function CardFooter({ ...props }: BitCardProps) {
-  const { className, font } = props;
+function CardFooter({ className, font, ...rest }: BitCardProps) {
@@
-    <ShadcnCardFooter
+    <ShadcnCardFooter
       data-slot="card-footer"
-      className={cn(font !== "normal" && "retro", className)}
-      {...props}
-    />
+      className={cn(font !== "normal" && "retro", className)}
+      {...rest}
+    />
📝 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
"path": "components/ui/8bit/card.tsx",
"content": "import { type VariantProps, cva } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport {\n Card as ShadcnCard,\n CardAction as ShadcnCardAction,\n CardContent as ShadcnCardContent,\n CardDescription as ShadcnCardDescription,\n CardFooter as ShadcnCardFooter,\n CardHeader as ShadcnCardHeader,\n CardTitle as ShadcnCardTitle,\n} from \"@/components/ui/card\";\n\nimport \"./styles/retro.css\";\n\nexport const cardVariants = cva(\"\", {\n variants: {\n font: {\n normal: \"\",\n retro: \"retro\",\n },\n },\n defaultVariants: {\n font: \"retro\",\n },\n});\n\nexport interface BitCardProps\n extends React.ComponentProps<\"div\">,\n VariantProps<typeof cardVariants> {\n asChild?: boolean;\n}\n\nfunction Card({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <div\n className={cn(\n \"relative border-y-6 border-foreground dark:border-ring !p-0\",\n className\n )}\n >\n <ShadcnCard\n {...props}\n className={cn(\n \"rounded-none border-0 !w-full\",\n font !== \"normal\" && \"retro\",\n className\n )}\n />\n\n <div\n className=\"absolute inset-0 border-x-6 -mx-1.5 border-foreground dark:border-ring pointer-events-none\"\n aria-hidden=\"true\"\n />\n </div>\n );\n}\n\nfunction CardHeader({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardHeader\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardTitle\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardDescription\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardAction\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardContent\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nfunction CardFooter({ ...props }: BitCardProps) {\n const { className, font } = props;\n\n return (\n <ShadcnCardFooter\n data-slot=\"card-footer\"\n className={cn(font !== \"normal\" && \"retro\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n};\n",
"type": "registry:component",
"target": "components/ui/8bit/card.tsx"
}
import { type VariantProps, cva } from "class-variance-authority";
import { cn } from "@/lib/utils";
import {
Card as ShadcnCard,
CardAction as ShadcnCardAction,
CardContent as ShadcnCardContent,
CardDescription as ShadcnCardDescription,
CardFooter as ShadcnCardFooter,
CardHeader as ShadcnCardHeader,
CardTitle as ShadcnCardTitle,
} from "@/components/ui/card";
import "./styles/retro.css";
export const cardVariants = cva("", {
variants: {
font: {
normal: "",
retro: "retro",
},
},
defaultVariants: {
font: "retro",
},
});
export interface BitCardProps
extends React.ComponentProps<"div">,
VariantProps<typeof cardVariants> {
asChild?: boolean;
}
function Card({ className, font, ...rest }: BitCardProps) {
return (
<div
className={cn(
"relative border-y-6 border-foreground dark:border-ring !p-0",
className
)}
>
<ShadcnCard
{...rest}
className={cn(
"rounded-none border-0 !w-full",
font !== "normal" && "retro",
className
)}
/>
<div
className="absolute inset-0 border-x-6 -mx-1.5 border-foreground dark:border-ring pointer-events-none"
aria-hidden="true"
/>
</div>
);
}
function CardHeader({ className, font, ...rest }: BitCardProps) {
return (
<ShadcnCardHeader
className={cn(font !== "normal" && "retro", className)}
{...rest}
/>
);
}
function CardTitle({ className, font, ...rest }: BitCardProps) {
return (
<ShadcnCardTitle
className={cn(font !== "normal" && "retro", className)}
{...rest}
/>
);
}
function CardDescription({ className, font, ...rest }: BitCardProps) {
return (
<ShadcnCardDescription
className={cn(font !== "normal" && "retro", className)}
{...rest}
/>
);
}
function CardAction({ className, font, ...rest }: BitCardProps) {
return (
<ShadcnCardAction
className={cn(font !== "normal" && "retro", className)}
{...rest}
/>
);
}
function CardContent({ className, font, ...rest }: BitCardProps) {
return (
<ShadcnCardContent
className={cn(font !== "normal" && "retro", className)}
{...rest}
/>
);
}
function CardFooter({ className, font, ...rest }: BitCardProps) {
return (
<ShadcnCardFooter
data-slot="card-footer"
className={cn(font !== "normal" && "retro", className)}
{...rest}
/>
);
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
};
🤖 Prompt for AI Agents
In public/r/8bit-chapter-intro.json (components/ui/8bit/card.tsx) around lines
24-28, wrapper components are forwarding the variant prop "font" into DOM by
spreading {...props}; destructure variant props out (e.g., const { className,
font, ...rest } = props) and spread only the remaining props ({...rest}) into
the Shadcn primitives (and not into DOM elements), update every function (Card,
CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter) to
stop passing font to children.

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