Skip to main content Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-react --skill component-libraryLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Métiers associés SOC
Basé sur la classification professionnelle SOC
Explorateur de fichiers
4 fichiers 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