Skip to content

Conversation

@MananTank
Copy link
Member

@MananTank MananTank commented Aug 27, 2025


PR-Codex overview

This PR focuses on enhancing the UI components in the project by restructuring imports, adding new features, and improving configuration for Storybook, along with dependency updates.

Detailed summary

  • Updated tailwind.config.ts to include .storybook content.
  • Refactored import paths for Button and Input components.
  • Introduced Badge component with variants.
  • Added custom Storybook configuration for absolute paths.
  • Updated pnpm-lock.yaml for new dependencies and versions.
  • Enhanced preview.tsx for Storybook with a theme toggle feature.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Shared Badge and Input components added to the UI package and exposed to apps.
    • Themed Storybook for the UI library with mobile viewports, notifications, data-fetching context, and an in-app theme toggle.
  • Refactor

    • Apps now re-export Badge/Input from the shared UI package; story layout and utilities centralized.
  • Chores

    • Storybook script and dependencies added, Tailwind scanning updated, and import paths standardized.

@vercel
Copy link

vercel bot commented Aug 27, 2025

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

Project Deployment Preview Comments Updated (UTC)
docs-v2 Ready Ready Preview Comment Aug 27, 2025 11:27pm
nebula Ready Ready Preview Comment Aug 27, 2025 11:27pm
thirdweb_playground Ready Ready Preview Comment Aug 27, 2025 11:27pm
thirdweb-www Ready Ready Preview Comment Aug 27, 2025 11:27pm
wallet-ui Ready Ready Preview Comment Aug 27, 2025 11:27pm

@changeset-bot
Copy link

changeset-bot bot commented Aug 27, 2025

⚠️ No Changeset found

Latest commit: afd1150

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

This PR includes no changesets

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

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

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 27, 2025

Walkthrough

Adds a new shared UI package (packages/ui) with Badge and Input components and Storybook setup; replaces several app-local Badge/Input implementations with re-exports to @workspace/ui; adds Storybook main/preview for the UI package, storybook utilities, tailwind/storybook config, and package.json dependency/script updates.

Changes

Cohort / File(s) Summary
Dashboard Storybook preview tweaks
apps/dashboard/.storybook/preview.tsx
Switched local imports to @workspace/ui paths, consolidated React imports, adjusted import ordering and biome-ignore directive, and simplified StoryLayout typing; runtime behavior preserved.
App-level Badge re-exports
apps/dashboard/src/@/components/ui/badge.tsx, apps/playground-web/src/components/ui/badge.tsx, apps/portal/src/components/ui/badge.tsx
Removed local Badge, badgeVariants, and props definitions; now re-export Badge, badgeVariants, and BadgeProps type from @workspace/ui/components/badge.
App-level Input re-exports
apps/dashboard/src/@/components/ui/input.tsx, apps/playground-web/src/components/ui/input.tsx, apps/portal/src/components/ui/input.tsx
Removed local forwardRef Input implementations and InputProps; files now re-export Input from @workspace/ui/components/input.
UI package Storybook config
packages/ui/.storybook/main.ts, packages/ui/.storybook/preview.tsx
Added Storybook main and Next.js preview: absolute-path helper, Inter/font and global CSS, QueryClientProvider, ThemeProvider, custom viewports, controls, theme toggle UI, Toaster, and exported preview config.
Shared UI components added
packages/ui/src/components/badge.tsx, packages/ui/src/components/input.tsx, packages/ui/src/components/button.stories.tsx
Added shared Badge (with badgeVariants) and Input components; adjusted Button story import path to @/components/button.
UI Storybook utilities
packages/ui/src/storybook/utils.tsx
Added internal StoryBadge, exported BadgeContainer component, and exported storybookLog(...mesages: unknown[]).
UI package configuration
packages/ui/package.json, packages/ui/tailwind.config.ts
Added runtime deps (@tanstack/react-query, lucide-react, next, next-themes, sonner), Storybook dev deps and storybook script; added .storybook/**/*.{ts,tsx} to Tailwind content.
Portal knip ignore update
apps/portal/knip.json
Added class-variance-authority to ignored dependencies and adjusted trailing-comma formatting.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant SB as Storybook UI
  participant Preview as packages/ui Preview
  participant Providers as ThemeProvider & QueryClientProvider
  participant Story as Story Component
  participant Toaster as Toaster

  User->>SB: select story
  SB->>Preview: render story
  Preview->>Providers: wrap story (theme, react-query)
  Providers->>Story: render story component
  Story-->>Toaster: emit notifications (optional)
  Note right of Preview: Inter font, theme toggle, viewports configured
Loading
sequenceDiagram
  autonumber
  participant Story as Story file
  participant Utils as packages/ui/src/storybook/utils.tsx

  Story->>Utils: import BadgeContainer & storybookLog
  Story->>Utils: use BadgeContainer to render labeled wrapper
  Story->>Utils: call storybookLog(...messages)
  Utils-->>Story: console.debug("Storybook", ...messages)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 08-27-packages_ui_add_storybook

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

@MananTank MananTank marked this pull request as ready for review August 27, 2025 11:57
@MananTank MananTank requested review from a team as code owners August 27, 2025 11:57
@github-actions github-actions bot added Dashboard Involves changes to the Dashboard. Playground Changes involving the Playground codebase. Portal Involves changes to the Portal (docs) codebase. packages labels Aug 27, 2025
Copy link
Member Author

MananTank commented Aug 27, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@MananTank MananTank changed the title packages/ui: Add storybook packages/ui: Add storybook, move Badge, Input to shared lib Aug 27, 2025
@codecov
Copy link

codecov bot commented Aug 27, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.54%. Comparing base (f79672e) to head (afd1150).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7923   +/-   ##
=======================================
  Coverage   56.53%   56.54%           
=======================================
  Files         904      904           
  Lines       58592    58592           
  Branches     4143     4140    -3     
=======================================
+ Hits        33126    33131    +5     
+ Misses      25360    25355    -5     
  Partials      106      106           
Flag Coverage Δ
packages 56.54% <ø> (+<0.01%) ⬆️
see 2 files with indirect coverage changes
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MananTank MananTank force-pushed the 08-27-packages_ui_add_storybook branch from 1b0a434 to 440fdce Compare August 27, 2025 12:00
@MananTank MananTank changed the title packages/ui: Add storybook, move Badge, Input to shared lib packages/ui: Add storybook, Add Badge, Input Aug 27, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Aug 27, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.06 KB (0%) 1.3 s (0%) 391 ms (+92.73% 🔺) 1.7 s
thirdweb (cjs) 357.05 KB (0%) 7.2 s (0%) 1.7 s (+9.82% 🔺) 8.8 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 112 ms (+535.04% 🔺) 227 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 35 ms (+543.66% 🔺) 45 ms
thirdweb/react (minimal + tree-shaking) 19.15 KB (0%) 383 ms (0%) 99 ms (+184% 🔺) 482 ms

Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
apps/dashboard/.storybook/preview.tsx (1)

39-43: Add the viewport addon to Storybook config

The dashboard Storybook is currently missing the @storybook/addon-viewport, so the toolbar won’t render your custom viewports. Please update your main configuration:

• File: apps/dashboard/.storybook/main.ts
• In the addons array, include the viewport addon:

module.exports = {
  // …
  addons: [
+   '@storybook/addon-viewport',
    /* existing addons */
  ],
  // …
};

This ensures the viewport toolbar appears when you’ve set custom viewports under parameters.viewport.

🧹 Nitpick comments (17)
packages/ui/src/components/button.stories.tsx (2)

14-16: Optional: add controls to make this story interactive.

You can expose Button props via args for quick ad‑hoc testing in Canvas.

 export const AllVariants: Story = {
-  args: {},
+  args: { size: "default", variant: "primary" },
 };

3-3: Ensure Storybook resolves the @ alias in the UI package

We verified that packages/ui/tsconfig.json defines

"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }

but the Storybook config at packages/ui/.storybook/main.ts does not include any webpackFinal hook, resolve.alias override, or use of TsconfigPathsPlugin. Without this, imports like

import { Button } from "@/components/button";

will not be resolved by Storybook and will cause build failures.

Please address this by choosing one of the following options:

• Option A – Wire up tsconfig paths in Storybook’s webpack config

  1. Install the plugin:
    npm install --save-dev tsconfig-paths-webpack-plugin
  2. Update packages/ui/.storybook/main.ts to include a webpackFinal hook:
    import { dirname, join } from "node:path";
    import type { StorybookConfig } from "@storybook/nextjs";
  • import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";

    function getAbsolutePath(value: string): string {
    return dirname(require.resolve(join(value, "package.json")));
    }

    const config: StorybookConfig = {
    stories: ["../src/**/*.stories.tsx"],
    addons: [
    getAbsolutePath("@storybook/addon-onboarding"),
    getAbsolutePath("@storybook/addon-links"),
    getAbsolutePath("@chromatic-com/storybook"),
    getAbsolutePath("@storybook/addon-docs"),
    ],
    framework: {
    name: getAbsolutePath("@storybook/nextjs"),
    options: {},
    },

  •  webpackFinal: async (storybookConfig) => {
    
  •    storybookConfig.resolve = storybookConfig.resolve || {};
    
  •    storybookConfig.resolve.plugins = [
    
  •      ...(storybookConfig.resolve.plugins || []),
    
  •      new TsconfigPathsPlugin({
    
  •        configFile: path.resolve(__dirname, "../tsconfig.json"),
    
  •      }),
    
  •    ];
    
  •    return storybookConfig;
    
  •  },
     features: {
       experimentalRSC: true,
     },
    

    };
    export default config;

    
    

• Option B – Convert the story to use a relative import:

— packages/ui/src/components/button.stories.tsx
  import React from "react";
- import { Button } from "@/components/button";
+ import { Button } from "./button";

  export default {
    component: Button,
    title: "Components/Button",
  };
packages/ui/.storybook/main.ts (2)

14-19: Add viewport and controls addons to match preview parameters.

preview.tsx configures custom viewports and controls. Without these addons, the toolbar panels won’t appear.

   addons: [
     getAbsolutePath("@storybook/addon-onboarding"),
     getAbsolutePath("@storybook/addon-links"),
     getAbsolutePath("@chromatic-com/storybook"),
-    getAbsolutePath("@storybook/addon-docs"),
+    getAbsolutePath("@storybook/addon-docs"),
+    getAbsolutePath("@storybook/addon-controls"),
+    getAbsolutePath("@storybook/addon-viewport"),
   ],

1-10: Suggestion: Add ESM-safe require only if/when migrating to ESM

The packages/ui/.storybook/main.ts file currently uses CommonJS require, and neither the root nor packages/ui package.json declares "type": "module", so require is available today. If and when you convert this package (or the repo) to ESM, plain require will break at runtime. At that point, you can switch to createRequire to preserve require.resolve behavior:

• File: packages/ui/.storybook/main.ts
• Snippet:

 import { dirname, join } from "node:path";
+import { createRequire } from "node:module";
+const require = createRequire(import.meta.url);

 /**
  * This function is used to resolve the absolute path of a package.
  * It is needed in projects that use Yarn PnP or are set up within a monorepo.
  */
 function getAbsolutePath(value: string): string {
   return dirname(require.resolve(join(value, "package.json")));
 }

No change is strictly needed now—keep using CommonJS require until you adopt ESM. When you do, apply the above diff to ensure require.resolve continues to work.

apps/dashboard/.storybook/preview.tsx (1)

74-76: Avoid overwriting body className; append classes instead.

Overwriting can drop classes added by Storybook/addons. Append to classList to keep other body classes.

-  useEffect(() => {
-    document.body.className = `font-sans antialiased ${fontSans.variable}`;
-  }, []);
+  useEffect(() => {
+    document.body.classList.add("font-sans", "antialiased");
+    // fontSans.variable is already a class name like `__className_xyz`
+    document.body.classList.add(fontSans.variable);
+    return () => {
+      document.body.classList.remove("font-sans", "antialiased", fontSans.variable);
+    };
+  }, []);
packages/ui/src/components/input.tsx (2)

8-9: Default input type to "text".

Avoids an undefined type and matches expected semantics.

-  ({ className, type, ...props }, ref) => {
+  ({ className, type = "text", ...props }, ref) => {

4-6: Prefer a type alias over interface per guidelines.

Semantically identical here and matches the codebase convention.

-export interface InputProps
-  extends React.InputHTMLAttributes<HTMLInputElement> {}
+export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
packages/ui/.storybook/preview.tsx (3)

12-13: Avoid React Query cache bleed between stories by scoping a fresh QueryClient per story

Creating a single module-level client shares cache across stories and can cause surprising results.

Refactor to create the client inside the decorator and remove the provider from StoryLayout:

-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
@@
-const queryClient = new QueryClient();
+// QueryClient is created per-story in the decorator to avoid cache bleed.
@@
   decorators: [
     (Story) => {
-      return (
-        <ThemeProvider
+      const queryClient = new QueryClient({
+        defaultOptions: { queries: { retry: false } },
+      });
+      return (
+        <ThemeProvider
           attribute="class"
           disableTransitionOnChange
           enableSystem={false}
           defaultTheme="dark"
         >
-          <StoryLayout>
-            <Story />
-          </StoryLayout>
+          <QueryClientProvider client={queryClient}>
+            <StoryLayout>
+              <Story />
+            </StoryLayout>
+          </QueryClientProvider>
         </ThemeProvider>
       );
     },
   ],
@@
-  return (
-    <QueryClientProvider client={queryClient}>
-      <div className="flex min-h-dvh min-w-0 flex-col bg-background text-foreground">
+  return (
+    <div className="flex min-h-dvh min-w-0 flex-col bg-background text-foreground">
@@
-      </div>
-    </QueryClientProvider>
+      </div>
   );

Also applies to: 51-66, 79-100


82-94: Nit: show the target theme icon and add a11y labels

Improves clarity and accessibility for the toggle.

Patch:

         <Button
           onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
           size="sm"
           variant="outline"
           className="h-auto w-auto shrink-0 rounded-full p-2"
+          aria-label={`Switch to ${theme === "dark" ? "light" : "dark"} theme`}
+          title={`Switch to ${theme === "dark" ? "light" : "dark"} theme`}
         >
-          {theme === "dark" ? (
-            <MoonIcon className="size-4" />
-          ) : (
-            <SunIcon className="size-4" />
-          )}
+          {theme === "dark" ? (
+            <SunIcon className="size-4" />
+          ) : (
+            <MoonIcon className="size-4" />
+          )}
         </Button>

71-71: Add explicit return types per repo TS guidelines

Keeps TS surfaces consistent across the UI package.

Apply:

-function StoryLayout(props: { children: React.ReactNode }) {
+function StoryLayout(props: { children: React.ReactNode }): JSX.Element {
@@
-function ToasterSetup() {
+function ToasterSetup(): JSX.Element {

Also applies to: 103-106

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

29-36: Prefer span for inline semantics

Badge is an inline element; span avoids unexpected block semantics in flow content.

-export interface BadgeProps
-  extends React.HTMLAttributes<HTMLDivElement>,
+export interface BadgeProps
+  extends React.HTMLAttributes<HTMLSpanElement>,
     VariantProps<typeof badgeVariants> {}
 
 function Badge({ className, variant, ...props }: BadgeProps) {
   return (
-    <div className={cn(badgeVariants({ variant }), className)} {...props} />
+    <span className={cn(badgeVariants({ variant }), className)} {...props} />
   );
 }
apps/dashboard/src/@/components/ui/badge.tsx (1)

1-1: Forward BadgeProps as a type for consistency.
Preempt type-only import regressions.

 export { Badge, badgeVariants } from "@workspace/ui/components/badge";
+export type { BadgeProps } from "@workspace/ui/components/badge";
apps/playground-web/src/components/ui/badge.tsx (1)

1-1: Consider re-exporting BadgeProps for type consumers.
Keeps local import sites working if they pull BadgeProps from this path.

 export { Badge, badgeVariants } from "@workspace/ui/components/badge";
+export type { BadgeProps } from "@workspace/ui/components/badge";
packages/ui/src/storybook/utils.tsx (3)

4-13: Add explicit return type to comply with TS guidelines.

-function StoryBadge(props: { label: string }) {
+function StoryBadge(props: { label: string }): JSX.Element {

27-33: Rename mesages -> messages and add return type.
Tiny typo; makes logs clearer and satisfies explicit return types.

-export function storybookLog(...mesages: unknown[]) {
-  console.debug(
+export function storybookLog(...messages: unknown[]): void {
+  console.debug(
     "%cStorybook",
     "color: white; background-color: black; padding: 2px 4px; border-radius: 4px;",
-    ...mesages,
+    ...messages,
   );
 }

1-1: Import ReactNode and add explicit return type

Confirmed that packages/ui/tsconfig.json uses "jsx": "preserve", so TypeScript won’t automatically provide a global React namespace for types. It’s therefore best to import the ReactNode type explicitly and annotate the function’s return type.

Please update in packages/ui/src/storybook/utils.tsx:

  • At the top of the file, add:
    import type { ReactNode } from "react";
  • Change the BadgeContainer signature (also applies to lines 15–18):
    +import type { ReactNode } from "react";
    @@
    -export function BadgeContainer(props: {
    -  label: string;
    -  children: React.ReactNode;
    -}) {
    +export function BadgeContainer(
    +  props: { label: string; children: ReactNode },
    +): JSX.Element {

This makes the component’s props and return type explicit and avoids potential TS errors around the React namespace.

packages/ui/package.json (1)

16-29: Right-size ui deps for optimal bundle
All Storybook-only packages can live in devDependencies, and shared libs should be peers to prevent duplicate bundles.

• packages/ui/package.json (dependencies → devDependencies/peerDependencies)

 "dependencies": {
   "@radix-ui/react-label": "^2.1.7",
   "@radix-ui/react-slot": "^1.2.3",
-  "@tanstack/react-query": "5.81.5",
   "class-variance-authority": "^0.7.1",
   "clsx": "^2.1.1",
-  "lucide-react": "0.525.0",
-  "next": "15.3.5",
-  "next-themes": "^0.4.6",
-  "sonner": "2.0.6",
   "tailwind-merge": "^2.6.0",
-  "tailwindcss-animate": "^1.0.7",
-  "thirdweb": "workspace:*"
+  "tailwindcss-animate": "^1.0.7"
 },
 "peerDependencies": {
+  "lucide-react": "^0.525.0",
+  "next": ">=14 <16",
   "react": "^19.0.0",
   "react-dom": "^19.0.0"
 },
 "devDependencies": {
   "@chromatic-com/storybook": "4.0.1",
   "@storybook/addon-docs": "9.0.15",
   "@storybook/addon-links": "9.0.15",
   "@storybook/addon-onboarding": "9.0.15",
   "@storybook/nextjs": "9.0.15",
+  "@tanstack/react-query": "5.81.5",
   "@types/react": "19.1.8",
   "@types/react-dom": "19.1.6",
   "autoprefixer": "^10.4.21",
   "postcss": "8.5.6",
   "storybook": "9.0.15",
   "tailwindcss": "3.4.17",
   "typescript": "5.8.3",
+  "thirdweb": "workspace:*",
+  "next-themes": "^0.4.6",
+  "sonner": "2.0.6",
+  "next": "15.3.5"
 }

• Verified no runtime imports of thirdweb, react-query, next-themes, sonner, or next outside Storybook code.

📜 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 e651d0a and 440fdce.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • apps/dashboard/.storybook/preview.tsx (2 hunks)
  • apps/dashboard/src/@/components/ui/badge.tsx (1 hunks)
  • apps/dashboard/src/@/components/ui/input.tsx (1 hunks)
  • apps/playground-web/src/components/ui/badge.tsx (1 hunks)
  • apps/playground-web/src/components/ui/input.tsx (1 hunks)
  • apps/portal/src/components/ui/badge.tsx (1 hunks)
  • apps/portal/src/components/ui/input.tsx (1 hunks)
  • packages/ui/.storybook/main.ts (1 hunks)
  • packages/ui/.storybook/preview.tsx (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/badge.tsx (1 hunks)
  • packages/ui/src/components/button.stories.tsx (1 hunks)
  • packages/ui/src/components/input.tsx (1 hunks)
  • packages/ui/src/storybook/utils.tsx (1 hunks)
  • packages/ui/tailwind.config.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

Files:

  • packages/ui/tailwind.config.ts
  • packages/ui/src/components/input.tsx
  • packages/ui/src/components/button.stories.tsx
  • packages/ui/src/storybook/utils.tsx
  • apps/portal/src/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • packages/ui/src/components/badge.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • apps/portal/src/components/ui/badge.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/ui/tailwind.config.ts
  • packages/ui/src/components/input.tsx
  • packages/ui/src/components/button.stories.tsx
  • packages/ui/src/storybook/utils.tsx
  • apps/portal/src/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • packages/ui/src/components/badge.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • apps/portal/src/components/ui/badge.tsx
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

For new UI components, add Storybook stories (*.stories.tsx) alongside the code

Files:

  • packages/ui/src/components/button.stories.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/input.tsx
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/wallets/page.tsx:1-1
Timestamp: 2025-08-20T10:37:10.123Z
Learning: In apps/dashboard, prefer importing UI components from "workspace/ui/components/*" where possible, as per jnsdls preference, rather than from "@/components/ui/*".
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code

Applied to files:

  • packages/ui/.storybook/main.ts
  • packages/ui/tailwind.config.ts
  • packages/ui/src/components/button.stories.tsx
  • packages/ui/src/storybook/utils.tsx
  • packages/ui/.storybook/preview.tsx
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{stories,test}.{tsx,ts} : Provide a Storybook story (`MyComponent.stories.tsx`) or unit test alongside the component.

Applied to files:

  • packages/ui/.storybook/main.ts
  • packages/ui/tailwind.config.ts
  • packages/ui/src/components/button.stories.tsx
  • packages/ui/.storybook/preview.tsx
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules

Applied to files:

  • packages/ui/tailwind.config.ts
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.

Applied to files:

  • packages/ui/src/components/button.stories.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Applied to files:

  • packages/ui/src/components/button.stories.tsx
  • apps/portal/src/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • apps/portal/src/components/ui/badge.tsx
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-05-30T17:14:25.332Z
Learnt from: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.

Applied to files:

  • packages/ui/src/storybook/utils.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to src/exports/react.native.ts : React Native specific exports are in `src/exports/react.native.ts`

Applied to files:

  • apps/portal/src/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/playground-web/src/components/ui/input.tsx
📚 Learning: 2025-08-20T10:37:10.123Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/wallets/page.tsx:1-1
Timestamp: 2025-08-20T10:37:10.123Z
Learning: In apps/dashboard, prefer importing UI components from "workspace/ui/components/*" where possible, as per jnsdls preference, rather than from "@/components/ui/*".

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Applied to files:

  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.

Applied to files:

  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Use React Query (`tanstack/react-query`) for all client data fetching.

Applied to files:

  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • apps/dashboard/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)

Applied to files:

  • apps/dashboard/.storybook/preview.tsx
🧬 Code graph analysis (1)
packages/ui/src/storybook/utils.tsx (3)
packages/ui/src/components/badge.tsx (1)
  • Badge (39-39)
packages/thirdweb/test/src/test-clients.js (1)
  • clientId (3-3)
packages/thirdweb/src/exports/thirdweb.ts (1)
  • createThirdwebClient (24-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (13)
packages/ui/tailwind.config.ts (1)

8-8: LGTM: include Storybook files in Tailwind content scan.

This prevents missing classes in stories. No further action.

apps/dashboard/.storybook/preview.tsx (1)

2-5: Good: imports centralized to workspace UI.

Imports align with the workspace convention (per jnsdls preference), reducing duplication across apps.

packages/ui/src/components/input.tsx (2)

7-21: LGTM overall.

ForwardRef typing, class merge via cn, and export are solid.


2-2: Alias Configuration Verified – Please Test Storybook Import Resolution

  • packages/ui/tsconfig.json defines
    • baseUrl: "."
    • paths: { "@/": ["./src/"] }
    (so the build will resolve @/lib/utils to packages/ui/src/lib/utils.ts)
  • The cn function is exported from packages/ui/src/lib/utils.ts, and the file exists as expected
  • Storybook is configured in packages/ui/.storybook/main.ts using the Next.js framework adapter, but there’s no explicit webpack alias or tsconfig-paths plugin applied

Please start Storybook locally and confirm that importing via import { cn } from "@/lib/utils"; does not error. If Storybook cannot resolve the @ alias, add one of the following to packages/ui/.storybook/main.ts:

• Use the tsconfig-paths-webpack-plugin:

import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';

export default {
  // …
  webpackFinal: async (config) => {
+   config.resolve.plugins = [
+     ...(config.resolve.plugins || []),
+     new TsconfigPathsPlugin({ configFile: '../tsconfig.json' }),
+   ];
    return config;
  },
};

• Or switch to a relative import:

-import { cn } from "@/lib/utils";
+import { cn } from "../lib/utils";
apps/dashboard/src/@/components/ui/input.tsx (1)

1-1: Add central InputProps re-export

To preserve typing and allow downstream modules to import the props type alongside the component, add the following line to apps/dashboard/src/@/components/ui/input.tsx. We’ve verified that no existing call sites import InputProps from this file, so introducing the re-export is safe and non-breaking.

 export { Input } from "@workspace/ui/components/input";
+export type { InputProps } from "@workspace/ui/components/input";

File to update:

  • apps/dashboard/src/@/components/ui/input.tsx
apps/playground-web/src/components/ui/input.tsx (1)

1-1: Approve: Add InputProps re-export

No existing references to InputProps were found in apps/playground-web (aside from the substring match in AggregateParameterInputProps), but exporting the type now ensures downstream stories/tests won’t break if they start importing it.

• Diff remains unchanged:

 export { Input } from "@workspace/ui/components/input";
+export type { InputProps } from "@workspace/ui/components/input";
packages/ui/src/components/badge.tsx (2)

6-27: Good use of cva; variants and defaults read cleanly

Variant set looks sensible and tokens align with the design system.


4-4: Verify build setup for @/* alias or switch to relative import

  • packages/ui/tsconfig.json defines
    "compilerOptions": {
      "paths": {
        "@/*": ["./src/*"]
      }
    }
    confirming that @/lib/utils resolves to packages/ui/src/lib/utils.ts.
  • The cn helper is exported from packages/ui/src/lib/utils.ts.
  • In packages/ui/src/components/badge.tsx, the import is currently:
    import { cn } from "@/lib/utils";

TypeScript’s path alias is only used at compile time and does not rewrite import paths in the emitted JavaScript. Unless your build or bundler (e.g., Rollup/Vite with an alias plugin) is explicitly transforming @/* imports into relative paths, the published package will contain imports from "@/lib/utils", which consumers cannot resolve.

Please verify your build configuration. If your bundler does not handle this alias, update the import to a relative path:

- import { cn } from "@/lib/utils";
+ import { cn } from "../lib/utils";
apps/portal/src/components/ui/badge.tsx (1)

1-1: LGTM — centralized re-export keeps imports stable.
This aligns with the shared UI consolidation.

apps/dashboard/src/@/components/ui/badge.tsx (1)

1-1: LGTM — matches our dashboard convention of importing from "@/components/ui/*".
Keeps the public surface unchanged while sourcing from the workspace.

apps/playground-web/src/components/ui/badge.tsx (1)

1-1: LGTM — re-export pattern is consistent across apps.
No runtime logic; safe change.

packages/ui/src/storybook/utils.tsx (2)

2-2: Alias import is valid – no change needed

The packages/ui/tsconfig.json already defines a local path mapping

"paths": {
  "@/*": ["./src/*"]
}

so using

import { Badge } from "@/components/badge";

resolves correctly in both Storybook and your build. You can safely ignore the suggested relative-import refactor.

Likely an incorrect or invalid review comment.


35-41: No changes required for optional lazy client creation

A global search shows that storybookThirdwebClient is imported in well over a hundred story files across apps/dashboard, apps/nebula, and packages/ui. Converting the export to a lazy function would require updating every import site to call getStorybookThirdwebClient() instead of referencing storybookThirdwebClient directly. Given the high refactor cost and the fact that we configure NEXT_PUBLIC_STORYBOOK_TW_CLIENT_ID in our Storybook setup, it’s safe to keep the current import-time validation. We can revisit a lazy-creation refactor in the future if we encounter stories that don’t need the client and still fail due to missing env vars.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (3)
apps/dashboard/src/@/components/ui/input.tsx (2)

1-1: Optional: also re-export the prop type to avoid downstream type breaks

If consumers import type InputProps from this module, re-export it from the workspace package.

Apply if InputProps is exported upstream:

-export { Input } from "@workspace/ui/components/input";
+export { Input } from "@workspace/ui/components/input";
+export type { InputProps } from "@workspace/ui/components/input";

1-1: Gotcha: client boundary across re-exports

If Next flags a “Client Component” import error through this wrapper, add 'use client'; here to propagate the client boundary. Only do this if you hit the error to avoid widening the client graph.

Proposed change (only if needed):

+'use client';
 export { Input } from "@workspace/ui/components/input";
packages/ui/src/components/button.stories.tsx (1)

33-59: Add aria-label for icon-only buttons (a11y).

When size="icon", the button has no accessible name. Add an aria-label to each icon-only usage.

-        <Button size={props.size}>
+        <Button size={props.size} aria-label={props.size === "icon" ? "Star" : undefined}>
           {props.size === "icon" ? <StarIcon className="size-4" /> : "Default"}
         </Button>
-        <Button size={props.size} variant="primary">
+        <Button size={props.size} variant="primary" aria-label={props.size === "icon" ? "Star" : undefined}>
           {props.size === "icon" ? <StarIcon className="size-4" /> : "Primary"}
         </Button>
-        <Button size={props.size} variant="secondary">
+        <Button size={props.size} variant="secondary" aria-label={props.size === "icon" ? "Star" : undefined}>
           {props.size === "icon" ? (
             <StarIcon className="size-4" />
           ) : (
             "Secondary"
           )}
         </Button>
-        <Button size={props.size} variant="ghost">
+        <Button size={props.size} variant="ghost" aria-label={props.size === "icon" ? "Star" : undefined}>
           {props.size === "icon" ? <StarIcon className="size-4" /> : "Ghost"}
         </Button>
-        <Button size={props.size} variant="outline">
+        <Button size={props.size} variant="outline" aria-label={props.size === "icon" ? "Star" : undefined}>
           {props.size === "icon" ? <StarIcon className="size-4" /> : "Outline"}
         </Button>
-        <Button size={props.size} variant="destructive">
+        <Button size={props.size} variant="destructive" aria-label={props.size === "icon" ? "Star" : undefined}>
           {props.size === "icon" ? (
             <StarIcon className="size-4" />
           ) : (
             "Destructive"
           )}
         </Button>
📜 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 440fdce and 5ab3fe3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • apps/dashboard/.storybook/preview.tsx (2 hunks)
  • apps/dashboard/src/@/components/ui/badge.tsx (1 hunks)
  • apps/dashboard/src/@/components/ui/input.tsx (1 hunks)
  • apps/playground-web/src/components/ui/badge.tsx (1 hunks)
  • apps/playground-web/src/components/ui/input.tsx (1 hunks)
  • apps/portal/knip.json (1 hunks)
  • apps/portal/src/components/ui/badge.tsx (1 hunks)
  • apps/portal/src/components/ui/input.tsx (1 hunks)
  • packages/ui/.storybook/main.ts (1 hunks)
  • packages/ui/.storybook/preview.tsx (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/badge.tsx (1 hunks)
  • packages/ui/src/components/button.stories.tsx (1 hunks)
  • packages/ui/src/components/input.tsx (1 hunks)
  • packages/ui/src/storybook/utils.tsx (1 hunks)
  • packages/ui/tailwind.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
  • packages/ui/src/components/input.tsx
  • packages/ui/src/storybook/utils.tsx
  • packages/ui/.storybook/main.ts
  • packages/ui/tailwind.config.ts
  • apps/portal/src/components/ui/input.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • packages/ui/.storybook/preview.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/portal/src/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • packages/ui/src/components/badge.tsx
  • packages/ui/package.json
  • apps/dashboard/.storybook/preview.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

Files:

  • packages/ui/src/components/button.stories.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/ui/src/components/button.stories.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

For new UI components, add Storybook stories (*.stories.tsx) alongside the code

Files:

  • packages/ui/src/components/button.stories.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/components/ui/input.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/wallets/page.tsx:1-1
Timestamp: 2025-08-20T10:37:10.123Z
Learning: In apps/dashboard, prefer importing UI components from "workspace/ui/components/*" where possible, as per jnsdls preference, rather than from "@/components/ui/*".
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules

Applied to files:

  • apps/portal/knip.json
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code

Applied to files:

  • packages/ui/src/components/button.stories.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Applied to files:

  • packages/ui/src/components/button.stories.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.

Applied to files:

  • packages/ui/src/components/button.stories.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{stories,test}.{tsx,ts} : Provide a Storybook story (`MyComponent.stories.tsx`) or unit test alongside the component.

Applied to files:

  • packages/ui/src/components/button.stories.tsx
📚 Learning: 2025-08-20T10:37:10.123Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/wallets/page.tsx:1-1
Timestamp: 2025-08-20T10:37:10.123Z
Learning: In apps/dashboard, prefer importing UI components from "workspace/ui/components/*" where possible, as per jnsdls preference, rather than from "@/components/ui/*".

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to src/exports/react.native.ts : React Native specific exports are in `src/exports/react.native.ts`

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Size
  • GitHub Check: Build Packages
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
apps/dashboard/src/@/components/ui/input.tsx (2)

1-1: LGTM: centralized re-export keeps the @/components/ui/* surface stable

This aligns with the dashboard guideline to import primitives via @/components/ui/* while sourcing from the shared UI package.


1-1: No changes needed: @workspace/ui is already resolved and transpiled

The dashboard app installs @workspace/ui via your Yarn workspace and relies on Node’s module resolution instead of custom TS path aliases, so no paths entry is required in tsconfig.json. Your apps/dashboard/next.config.ts already lists:

transpilePackages: ["@workspace/ui"],

which ensures the UI package is compiled by Next.js.

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

3-3: Confirm alias resolution in Storybook configuration

  • packages/ui/tsconfig.json correctly maps "@/*": ["./src/*"] to the UI source folder.
  • .storybook/main.ts (using the @storybook/nextjs framework) has no explicit webpack alias or TsconfigPathsPlugin configured. Storybook will not automatically pick up your TS paths mappings without one of these.

Please verify (or add) one of the following in packages/ui/.storybook/main.ts to ensure import { Button } from "@/components/button" resolves correctly:

• Add a webpack alias:

import path from "path";
const config: StorybookConfig = {
  // …existing config…
  webpackFinal: async (config) => {
    config.resolve.alias = {
      ...(config.resolve.alias || {}),
      "@": path.resolve(__dirname, "../src"),
    };
    return config;
  },
};
export default config;

• Or register TsconfigPathsPlugin:

import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin";
const config: StorybookConfig = {
  // …existing config…
  webpackFinal: async (config) => {
    config.resolve.plugins = [
      ...(config.resolve.plugins || []),
      new TsconfigPathsPlugin({ extensions: config.resolve.extensions }),
    ];
    return config;
  },
};
export default config;

This will prevent any path-resolution issues in your UI stories.

apps/portal/knip.json (1)

23-25: cva and tailwindcss-animate confirmed unused — safe to ignore

Ripgrep across apps/portal found only entries in knip.json and package.json, and no direct imports in code or Tailwind config. Keeping them in the knip.json ignore list is correct.

Copy link
Contributor

@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

♻️ Duplicate comments (1)
packages/ui/.storybook/preview.tsx (1)

74-76: Don’t overwrite body.className; append and clean up instead

Overwriting can remove Storybook’s own classes and break theming/layout.

Apply:

-  useEffect(() => {
-    document.body.className = `font-sans antialiased ${fontSans.variable}`;
-  }, []);
+  useEffect(() => {
+    const classes = ["font-sans", "antialiased", fontSans.variable];
+    document.body.classList.add(...classes);
+    return () => {
+      document.body.classList.remove(...classes);
+    };
+  }, [fontSans.variable]);
🧹 Nitpick comments (3)
packages/ui/src/storybook/utils.tsx (2)

26-31: Typo in parameter name; add explicit return type

Minor nit: rename mesagesmessages; declare return type.

Apply:

-export function storybookLog(...mesages: unknown[]) {
+export function storybookLog(...messages: unknown[]): void {
   console.debug(
     "%cStorybook",
     "color: white; background-color: black; padding: 2px 4px; border-radius: 4px;",
-    ...mesages,
+    ...messages,
   );
 }

14-24: Optional: extract props type and explicit return types for exported APIs

Improves DX and satisfies our TS guidelines.

Apply:

-export function BadgeContainer(props: {
-  label: string;
-  children: React.ReactNode;
-}) {
+export type BadgeContainerProps = {
+  label: string;
+  children: React.ReactNode;
+};
+
+export function BadgeContainer(props: BadgeContainerProps): JSX.Element {
packages/ui/package.json (1)

16-28: Move Storybook-only dependencies to devDependencies

None of the following packages is imported by any runtime code under packages/ui/src/components (they only appear in .stories.tsx):
@tanstack/react-query
next
next-themes
sonner
lucide-react

Shifting them out of dependencies keeps the UI package lean and avoids unnecessary bloat or duplicate installs for consumers. Apply the diff below to move them into devDependencies:

--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -16,12 +16,8 @@
   "dependencies": {
     "@radix-ui/react-label": "^2.1.7",
     "@radix-ui/react-slot": "^1.2.3",
-    "@tanstack/react-query": "5.81.5",
     "class-variance-authority": "^0.7.1",
     "clsx": "^2.1.1",
-    "lucide-react": "0.525.0",
-    "next": "15.3.5",
-    "next-themes": "^0.4.6",
-    "sonner": "2.0.6",
     "tailwind-merge": "^2.6.0",
     "tailwindcss-animate": "^1.0.7"
   },
@@ -37,6 +33,11 @@
   "devDependencies": {
+    "@tanstack/react-query": "5.81.5",
+    "lucide-react": "0.525.0",
+    "next": "15.3.5",
+    "next-themes": "^0.4.6",
+    "sonner": "2.0.6",
     "@chromatic-com/storybook": "4.0.1",
     "@storybook/addon-docs": "9.0.15",
     "@storybook/addon-links": "9.0.15",
📜 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 1f5ed60 and 56a4ba2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • apps/dashboard/.storybook/preview.tsx (2 hunks)
  • apps/dashboard/src/@/components/ui/badge.tsx (1 hunks)
  • apps/dashboard/src/@/components/ui/input.tsx (1 hunks)
  • apps/playground-web/src/components/ui/badge.tsx (1 hunks)
  • apps/playground-web/src/components/ui/input.tsx (1 hunks)
  • apps/portal/knip.json (1 hunks)
  • apps/portal/src/components/ui/badge.tsx (1 hunks)
  • apps/portal/src/components/ui/input.tsx (1 hunks)
  • packages/ui/.storybook/main.ts (1 hunks)
  • packages/ui/.storybook/preview.tsx (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/badge.tsx (1 hunks)
  • packages/ui/src/components/button.stories.tsx (1 hunks)
  • packages/ui/src/components/input.tsx (1 hunks)
  • packages/ui/src/storybook/utils.tsx (1 hunks)
  • packages/ui/tailwind.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/ui/.storybook/main.ts
  • packages/ui/tailwind.config.ts
  • apps/portal/src/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • apps/portal/knip.json
  • apps/dashboard/src/@/components/ui/badge.tsx
  • apps/dashboard/.storybook/preview.tsx
  • apps/portal/src/components/ui/input.tsx
  • packages/ui/src/components/button.stories.tsx
  • packages/ui/src/components/input.tsx
  • packages/ui/src/components/badge.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

Files:

  • packages/ui/src/storybook/utils.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/ui/src/storybook/utils.tsx
  • apps/dashboard/src/@/components/ui/input.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/components/ui/input.tsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code

Applied to files:

  • packages/ui/src/storybook/utils.tsx
  • packages/ui/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{stories,test}.{tsx,ts} : Provide a Storybook story (`MyComponent.stories.tsx`) or unit test alongside the component.

Applied to files:

  • packages/ui/src/storybook/utils.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add `className` to the root element of every component for external overrides.

Applied to files:

  • packages/ui/.storybook/preview.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-08-20T10:37:10.123Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7888
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/wallets/page.tsx:1-1
Timestamp: 2025-08-20T10:37:10.123Z
Learning: In apps/dashboard, prefer importing UI components from "workspace/ui/components/*" where possible, as per jnsdls preference, rather than from "@/components/ui/*".

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to src/exports/react.native.ts : React Native specific exports are in `src/exports/react.native.ts`

Applied to files:

  • apps/dashboard/src/@/components/ui/input.tsx
📚 Learning: 2025-05-30T17:14:25.332Z
Learnt from: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-06-17T18:30:52.976Z
Learnt from: MananTank
PR: thirdweb-dev/js#7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.

Applied to files:

  • packages/ui/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: Build Packages
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/@/components/ui/input.tsx (1)

1-1: Add ’use client’ directive and re-export InputProps

To ensure this wrapper is treated as a Client Component and to preserve type imports, update apps/dashboard/src/@/components/ui/input.tsx as follows. Although our search didn’t find any current imports of InputProps, please verify manually in case there are references we missed.

• File: apps/dashboard/src/@/components/ui/input.tsx
• Change:

+ 'use client';
+
-export { Input } from "@workspace/ui/components/input";
+export { Input } from "@workspace/ui/components/input";
+export type { InputProps } from "@workspace/ui/components/input";

• After applying, double-check imports across both dashboard and playground-web apps for any direct type references to InputProps.

packages/ui/.storybook/preview.tsx (1)

51-67: Preview decorator structure looks good

ThemeProvider + layout wrapper pattern is solid for Storybook 9 + Next.js.

@graphite-app
Copy link
Contributor

graphite-app bot commented Aug 27, 2025

Merge activity

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces several updates focused on enhancing the UI components, improving Storybook integration, and updating dependencies. It also refactors some components for better modularity and performance.

### Detailed summary
- Added `class-variance-authority` and updated `tailwindcss-animate` in `knip.json`.
- Updated `tailwind.config.ts` to include `.storybook` directory in content.
- Refactored imports for `Button` and `Input` components.
- Created `Badge` component and its variants in `badge.tsx`.
- Updated Storybook configuration in `.storybook/main.ts` and `preview.tsx`.
- Refactored `Input` components in multiple locations to use a shared implementation.
- Added `Toaster` setup in Storybook preview for better notifications.
- Updated dependencies in `package.json` and `pnpm-lock.yaml`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Shared Badge and Input components added to the UI package and made available to apps.
  - Themed Storybook for the UI library with mobile viewports, notifications, data-fetching context, and an in-app theme toggle.

- **Refactor**
  - Apps now re-export Badge/Input from the shared UI package; story utilities and preview/layout centralized.

- **Chores**
  - Storybook script and dependencies added, Tailwind content updated, and import paths standardized.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Copy link
Contributor

@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: 0

Caution

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

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

1-25: Add Storybook story for Input component

Per team guidelines, every new UI primitive must include a Storybook story (*.stories.tsx). I didn’t find any existing input.stories.tsx under packages/ui/src/components/—please add one.

• Create a new file:
packages/ui/src/components/input.stories.tsx

• Include a basic CSF3 setup with controls and variants for default, disabled, and invalid states. For example:

+ import React from 'react';
+ import { Meta, Story } from '@storybook/react';
+ import { Input, InputProps } from './input';
+
+ const meta: Meta<InputProps> = {
+   title: 'Components/Input',
+   component: Input,
+   argTypes: {
+     placeholder: { control: 'text' },
+     disabled: { control: 'boolean' },
+     'aria-invalid': { control: 'boolean' },
+   },
+ };
+
+ export default meta;
+
+ const Template: Story<InputProps> = (args) => <Input {...args} />;
+
+ export const Default = Template.bind({});
+ Default.args = {
+   placeholder: 'Type here…',
+ };
+
+ export const Disabled = Template.bind({});
+ Disabled.args = {
+   disabled: true,
+   placeholder: 'Cannot type',
+ };
+
+ export const Invalid = Template.bind({});
+ Invalid.args = {
+   placeholder: 'Error state',
+   'aria-invalid': true,
+ };

Let me know if you’d like any help setting up controls or knobs!

🧹 Nitpick comments (2)
packages/ui/src/components/input.tsx (2)

4-6: Prefer a type alias for props per guidelines

Project guideline prefers type aliases over interfaces for structural types.

-export interface InputProps
-  extends React.InputHTMLAttributes<HTMLInputElement> {}
+export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;

7-21: Default to type='text'

Small DX win and parity with native default. Keeps intent explicit and avoids undefined drifting through.

-const Input = React.forwardRef<HTMLInputElement, InputProps>(
-  ({ className, type, ...props }, ref) => {
+const Input = React.forwardRef<HTMLInputElement, InputProps>(
+  ({ className, type = "text", ...props }, ref) => {
📜 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 56a4ba2 and afd1150.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • apps/dashboard/.storybook/preview.tsx (2 hunks)
  • apps/dashboard/src/@/components/ui/badge.tsx (1 hunks)
  • apps/dashboard/src/@/components/ui/input.tsx (1 hunks)
  • apps/playground-web/src/components/ui/badge.tsx (1 hunks)
  • apps/playground-web/src/components/ui/input.tsx (1 hunks)
  • apps/portal/knip.json (1 hunks)
  • apps/portal/src/components/ui/badge.tsx (1 hunks)
  • apps/portal/src/components/ui/input.tsx (1 hunks)
  • packages/ui/.storybook/main.ts (1 hunks)
  • packages/ui/.storybook/preview.tsx (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/badge.tsx (1 hunks)
  • packages/ui/src/components/button.stories.tsx (1 hunks)
  • packages/ui/src/components/input.tsx (1 hunks)
  • packages/ui/src/storybook/utils.tsx (1 hunks)
  • packages/ui/tailwind.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (15)
  • apps/portal/src/components/ui/badge.tsx
  • apps/playground-web/src/components/ui/input.tsx
  • apps/dashboard/src/@/components/ui/badge.tsx
  • packages/ui/.storybook/main.ts
  • packages/ui/tailwind.config.ts
  • apps/portal/knip.json
  • packages/ui/package.json
  • apps/dashboard/src/@/components/ui/input.tsx
  • packages/ui/src/storybook/utils.tsx
  • apps/portal/src/components/ui/input.tsx
  • apps/playground-web/src/components/ui/badge.tsx
  • packages/ui/.storybook/preview.tsx
  • apps/dashboard/.storybook/preview.tsx
  • packages/ui/src/components/badge.tsx
  • packages/ui/src/components/button.stories.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

Files:

  • packages/ui/src/components/input.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/ui/src/components/input.tsx
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.stories.tsx : For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
packages/ui/src/components/input.tsx (2)

10-18: LGTM: forwardRef + class merge are correct

  • Correct ref typing and displayName.
  • cn merge order allows consumer overrides; focus-visible/ring/disabled states are sensible.

1-2: Review alias usage in published UI package build

I ran a local check in packages/ui and found no evidence of an @/* alias being handled in this package:

  • packages/ui/tsconfig.json does not define a "@/*" path alias.
  • No tsup.config.* or other bundler config in this package mentions alias, tsconfig-paths, or esbuild plugins.
  • The local Storybook setup (.storybook/main.ts / preview.tsx) has no explicit alias resolution.

Unless you have a root-level alias resolver that applies to this package’s build and Storybook, the import

-import { cn } from "@/lib/utils";
+import { cn } from "../lib/utils";

will break for downstream consumers. Please either switch to the relative path above or configure alias resolution for both the package build and Storybook.

@graphite-app graphite-app bot merged commit afd1150 into main Aug 27, 2025
25 checks passed
@graphite-app graphite-app bot deleted the 08-27-packages_ui_add_storybook branch August 27, 2025 23:27
@vercel vercel bot temporarily deployed to Production – thirdweb_playground August 27, 2025 23:39 Inactive
@vercel vercel bot temporarily deployed to Production – docs-v2 August 27, 2025 23:53 Inactive
@vercel vercel bot temporarily deployed to Production – wallet-ui August 27, 2025 23:55 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Dashboard Involves changes to the Dashboard. packages Playground Changes involving the Playground codebase. Portal Involves changes to the Portal (docs) codebase.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants