Skip to main content المهن ذات الصلةSOC
استنادا إلى تصنيف SOC المهني
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-react --skill component-libraryيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
| name | component-library |
| description | Build production-grade, accessible, and tested component libraries with Storybook, Chromatic, and design tokens |
| sasmp_version | 2.0.0 |
| bonded_agent | 03-component-architecture |
| bond_type | PRIMARY_BOND |
| input_validation | {"required_packages":[{"storybook":">=7.0.0"},{"@storybook/react":">=7.0.0"}]} |
| output_format | {"code_examples":"tsx","test_template":"jest","storybook_template":"csf3"} |
| error_handling | {"patterns":["prop_validation","error_boundary","fallback_component"]} |
| observability | {"logging":"storybook_console","metrics":["component_coverage","a11y_score"]} |
Component Library Building Skill
Overview
Learn to build reusable, accessible, and well-documented component libraries for React applications using modern design patterns and tools.
Learning Objectives
- Design reusable component APIs
- Implement accessible components (WCAG 2.1)
- Create component variants and compositions
- Build documentation with Storybook
- Publish and maintain npm packages
Component Design Principles
1. Flexible and Composable
<Card>
<Card.Header>
<Card.Title>Title</Card.Title>
</Card.Header>
<Card.Body>Content</Card.Body>
<Card.Footer>
<Button>Action</Button>
</Card.Footer>
</Card>
<Card title="Title" content="Content" action="Action" />
2. Accessible by Default
function Button({ children, onClick, disabled, ...props }) {
return (
<button
type="button"
onClick=
=
=
{}
>
{children}
);
}
{onClick}
disabled
{disabled}
aria-disabled
{disabled}
...props
</button>
Essential Components
Button Component
const Button = forwardRef(({
children,
variant = 'primary',
size = 'md',
disabled = false,
loading = false,
leftIcon,
rightIcon,
...props
}, ref) => {
return (
<button
ref={ref}
className={`btn btn-${variant} btn-${size}`}
disabled={disabled || loading}
aria-busy={loading}
{...props}
>
{leftIcon && <span className="btn-icon-left">{leftIcon}</span>}
{loading ? <Spinner size="sm" /> : children}
{rightIcon && <span className="btn-icon-right">{rightIcon}</span>}
</button>
);
});
Button.displayName = 'Button';
Input Component
const Input = forwardRef(({
label,
error,
helper,
required,
...props
}, ref) => {
const id = useId();
return (
<div className="input-wrapper">
{label && (
<label htmlFor={id}>
{label}
{required && <span aria-label="required">*</span>}
</label>
)}
<input
ref={ref}
id={id}
aria-invalid={!!error}
aria-describedby={error ? `${id}-error` : helper ? `${id}-helper` : undefined}
{...props}
/>
{helper && <span id={`${id}-helper`} className="input-helper">{helper}</span>}
{error && <span id={`${id}-error`} className="input-error" role="alert">{error}</span>}
</div>
);
});
Modal Component
function Modal({ isOpen, onClose, title, children }) {
const modalRef = useRef(null);
useEffect(() => {
if (isOpen) {
const previousActiveElement = document.activeElement;
modalRef.current?.focus();
return () => {
previousActiveElement?.focus();
};
}
}, [isOpen]);
useOnClickOutside(modalRef, onClose);
if (!isOpen) return null;
return createPortal(
<div className="modal-overlay" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<div ref={modalRef} className="modal" tabIndex={-1}>
<div className="modal-header">
<h2 id="modal-title">{title}</h2>
<button onClick={onClose} aria-label="Close modal">×</button>
</div>
<div className="modal-body">{children}</div>
</div>
</div>,
document.body
);
}
Dropdown Component
function Dropdown({ trigger, children }) {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);
useOnClickOutside(dropdownRef, () => setIsOpen(false));
return (
<div ref={dropdownRef} className="dropdown">
<div onClick={() => setIsOpen(!isOpen)} role="button" aria-expanded={isOpen}>
{trigger}
</div>
{isOpen && (
<div className="dropdown-menu" role="menu">
{children}
</div>
)}
</div>
);
}
function DropdownItem({ onClick, children }) {
return (
<div className="dropdown-item" role="menuitem" onClick={onClick} tabIndex={0}>
{children}
</div>
);
}
Dropdown.Item = DropdownItem;
Compound Components Pattern
Tabs Component
const TabsContext = createContext();
function Tabs({ children, defaultTab }) {
const [activeTab, setActiveTab] = useState(defaultTab);
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}
function TabList({ children }) {
return <div className="tab-list" role="tablist">{children}</div>;
}
function Tab({ id, children }) {
const { activeTab, setActiveTab } = useContext(TabsContext);
return (
<button
role="tab"
aria-selected={activeTab === id}
onClick={() => setActiveTab(id)}
className={activeTab === id ? 'active' : ''}
>
{children}
</button>
);
}
function TabPanels({ children }) {
return <div className="tab-panels">{children}</div>;
}
function TabPanel({ id, children }) {
const { activeTab } = useContext(TabsContext);
if (activeTab !== id) return null;
return <div role="tabpanel">{children}</div>;
}
Tabs.List = TabList;
Tabs.Tab = Tab;
Tabs.Panels = TabPanels;
Tabs.Panel = TabPanel;
Storybook Integration
Installation
npx storybook@latest init
Button Stories
import { Button } from './Button';
export default {
title: 'Components/Button',
component: Button,
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'danger']
},
size: {
control: 'select',
options: ['sm', 'md', 'lg']
}
}
};
export const Primary = {
args: {
variant: 'primary',
children: 'Button'
}
};
export const WithIcons = {
args: {
leftIcon: <Icon name="star" />,
children: 'Button'
}
};
export const Loading = {
args: {
loading: true,
children: 'Loading...'
}
};
TypeScript Support
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'sm' | 'md' | 'lg';
loading?: boolean;
leftIcon?: React.ReactNode;
rightIcon?: React.ReactNode;
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ children, variant = 'primary', size = 'md', ...props }, ref) => {
return (
<button ref={ref} className={`btn btn-${variant} btn-${size}`} {...props}>
{children}
</button>
);
}
);
Publishing to npm
package.json Setup
{
"name": "@yourname/component-library",
"version": "1.0.0",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Practice Projects
- Build a complete Button component with variants
- Create accessible Form components (Input, Select, Checkbox)
- Implement Modal with focus trap
- Build Dropdown with keyboard navigation
- Create Tabs compound component
- Implement Toast notification system
- Build Tooltip component
Resources
Difficulty: Intermediate to Advanced
Estimated Time: 3-4 weeks
Prerequisites: React Fundamentals, Component Architecture