スキル一覧に戻る
allenlin90

frontend-ui-components

by allenlin90

1🍴 0📅 2026年1月24日
GitHubで見るManusで実行

SKILL.md


name: frontend-ui-components description: Provides guidelines for using shared UI components and styling. This skill should be used when implementing UI features using Shadcn/Radix components and the shared @eridu/ui package.

Frontend UI Components

This skill outlines how to build and use UI components in the frontend applications, leveraging the shared @eridu/ui package and Shadcn patterns.

The @eridu/ui Package

All generic UI components (Buttons, Inputs, Dialogs, etc.) live in packages/ui. Do NOT create local copies of generic components in apps.

Usage

import { Button } from '@eridu/ui/components/button';
import { Input } from '@eridu/ui/components/input';

export function MyForm() {
  return (
    <div className="flex gap-4">
      <Input placeholder="Search..." />
      <Button variant="default">Search</Button>
    </div>
  );
}

Styling Pattern (Tailwind CSS v4)

We use Tailwind CSS v4 with clsx and tailwind-merge for conditional styling.

The cn Utility

Use the cn utility from @eridu/ui/lib/utils to merge classes safely.

import { cn } from '@eridu/ui/lib/utils';

interface CardProps {
  className?: string;
  children: React.ReactNode;
}

export function Card({ className, children }: CardProps) {
  return (
    <div className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}>
      {children}
    </div>
  );
}

Component Design Patterns

Composition Over Large Components

Build complex UIs by composing small, focused components instead of creating large monolithic components.

Benefits:

  • Easier to test and maintain
  • Better performance (smaller re-render scope)
  • More reusable components
  • Clearer separation of concerns
// ❌ BAD: Large monolithic component
function UserDashboard() {
  return (
    <div>
      <header>{/* Complex header logic */}</header>
      <nav>{/* Complex navigation */}</nav>
      <main>
        <div>{/* User stats */}</div>
        <div>{/* Activity feed */}</div>
        <div>{/* Recommendations */}</div>
      </main>
      <footer>{/* Footer content */}</footer>
    </div>
  );
}

// ✅ GOOD: Composed from smaller components
function UserDashboard() {
  return (
    <div>
      <DashboardHeader />
      <DashboardNav />
      <main>
        <UserStats />
        <ActivityFeed />
        <Recommendations />
      </main>
      <DashboardFooter />
    </div>
  );
}

Using Children for Composition

Use the children prop to create flexible, composable components.

// Flexible Dialog component using composition
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@eridu/ui/components/dialog';

function ConfirmDeleteDialog({ isOpen, onClose, onConfirm }) {
  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Confirm Deletion</DialogTitle>
        </DialogHeader>
        <p>Are you sure you want to delete this item?</p>
        <div className="flex gap-2">
          <Button variant="outline" onClick={onClose}>Cancel</Button>
          <Button variant="destructive" onClick={onConfirm}>Delete</Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}

Wrapping 3rd Party Components

Wrap 3rd party components to adapt them to your application's needs and make future changes easier.

// Wrap Radix Link to add app-specific behavior
import { Link as RadixLink } from '@radix-ui/react-navigation-menu';
import { cn } from '@eridu/ui/lib/utils';

interface AppLinkProps extends React.ComponentPropsWithoutRef<typeof RadixLink> {
  external?: boolean;
}

export function Link({ external, className, children, ...props }: AppLinkProps) {
  return (
    <RadixLink
      className={cn('text-primary hover:underline', className)}
      target={external ? '_blank' : undefined}
      rel={external ? 'noopener noreferrer' : undefined}
      {...props}
    >
      {children}
      {external && <span className="ml-1">↗</span>}
    </RadixLink>
  );
}

When to Abstract Components

Abstract components into the shared @eridu/ui package when:

  1. Used in multiple apps - Component is needed across erify_creators, erify_studios, etc.
  2. Generic and reusable - Not tied to specific business logic
  3. Stable API - Interface is unlikely to change frequently
  4. Well-tested - Component has proper tests and documentation

Don't abstract too early:

  • Wait until you have 2-3 use cases before abstracting
  • Avoid premature abstraction (wrong abstractions are worse than duplication)
  • Keep feature-specific components in feature folders

Creating New Components

When creating app-specific features:

  1. Compose them using primitives from @eridu/ui.
  2. Keep them in src/components/{feature-name}/.

When creating new generic primitives:

  1. Add them to packages/ui/src/components/.
  2. Follow the Radix UI + Tailwind pattern (Shadcn style).
  3. Export them via packages/ui/package.json.

Checklist

  • Import generic components from @eridu/ui.
  • Use cn() for class merging.
  • Ensure components are accessible (Radix UI primitives).
  • Use Tailwind text/bg colors that map to the theme (e.g., bg-primary, text-muted-foreground).

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です