A small React UI component library (Badges, Banners, Cards, Testimonials) with a demo app. Built with Vite + React and designed to be publishable as an npm package or used directly in an app.
React component library with Badges, Banners, Cards, and Testimonials — built with Vite + React. Demo app included.
Clone and install dependencies:
# with npm
git clone https://github.com/joacopobre/Components-Library
cd Components-Library
npm install
npm run dev
# or with yarn
yarn
yarn dev
# or with pnpm
pnpm install
pnpm devThis starts the demo app so you can see all components rendered.
Import components directly from src when hacking locally:
import Badge from './src/components/Badges/Badge'
import Banner from './src/components/Banners/Banner'
import Card from './src/components/Cards/Card'
import Testimonial from './src/components/Testimonials/Testimonial'
export default function App() {
return (
<>
<Badge color="green">Success</Badge>
<Banner type="warning">Heads up! Please check your input.</Banner>
<Card type="download">Get the latest release</Card>
<Testimonial name="Leslie Alexander" job="CEO">
“This library helped us ship UI fast.”
</Testimonial>
</>
)
}If you publish to npm (see Build as a library):
import { Badge, Banner, Card, Testimonial } from '@your-scope/components-library'Note: This project uses Font Awesome icons in some components. If you consume the library, make sure your app has
@fortawesome/react-fontawesomeand@fortawesome/free-solid-svg-iconsinstalled, or keep them as peer dependencies.
A small label. Supports colors and an optional pill style.
<Badge>Gray</Badge>
<Badge color="red">Error</Badge>
<Badge color="green" variant="pill">Active</Badge>| Prop | Type | Default | Values | Description |
|---|---|---|---|---|
color |
string | gray |
gray red yellow green blue indigo purple pink |
Visual color theme |
variant |
string | "" |
"" (default), pill |
Pill corners if pill |
children |
ReactNode | — | — | Badge content |
Status/notice block with a title generated from the type.
<Banner type="success">Everything worked! You can proceed.</Banner>
<Banner type="warning">Heads up! Please check your input.</Banner>
<Banner type="error">There was a problem with your request.</Banner>
<Banner type="neutral">Update available.</Banner>| Prop | Type | Default | Values | Description |
|---|---|---|---|---|
type |
string | neutral |
success warning error neutral |
Controls color/title |
children |
ReactNode | — | — | Optional supporting text |
Compact information card with an optional icon based on type.
<Card type="download">Et magna sit morbi lobortis.</Card>
<Card type="upload">Auctor pellentesque rhoncus sapien.</Card>
<Card type="update">Ac tincidunt vehicula erat.</Card>| Prop | Type | Default | Values | Description |
|---|---|---|---|---|
type |
string | download |
download upload update |
Selects icon + title |
children |
ReactNode | — | — | Body text inside the card |
Icons use Font Awesome. Ensure
@fortawesome/react-fontawesomeand@fortawesome/free-solid-svg-iconsare available in your app, or keep them as peer dependencies.
Customer quote block. When imageSrc is provided, renders an avatar + large quote mark; otherwise a text-only layout.
<Testimonial name="Leslie Alexander" job="CEO">
“Lorem ipsum dolor sit amet, consectetur adipiscing elit…”
</Testimonial>
<Testimonial imageSrc={profile} name="Jacob Jones" job="Product Lead">
“Sed urna nulla vitae laoreet augue. Amet feugiat est integer…”
</Testimonial>| Prop | Type | Default | Description |
|---|---|---|---|
imageSrc |
string | null |
Optional image URL or imported asset |
name |
string | — | Person’s name (required) |
job |
string | — | Person’s role or title |
children |
ReactNode | — | The quote/testimonial text |
Accessibility hints:
- Provide meaningful
alttext if the image conveys information; leavealt=""if purely decorative. - Ensure focus order and semantics remain intact when wrapping these in links or interactive containers.
- The demo uses a global
src/index.cssfor simplicity. For real-world reuse, consider CSS Modules (e.g.,Badge.module.css) or a CSS-in-JS solution to avoid global collisions. - Key class hooks you can theme:
.badge,.badge.pill,.banner.success|warning|error|neutral,.card,.testimonial.with-icon,.testimonial.no-icon. - You can also expose CSS variables (e.g.,
--badge-bg,--banner-success) for easy theming.
src/
components/
Badges/
Badge.jsx
Badges.jsx
Banners/
Banner.jsx
Banners.jsx
Cards/
Card.jsx
Cards.jsx
Testimonials/
Testimonial.jsx
Testimonials.jsx
utils/ # Pure helpers (no React hooks)
buildBannerMessage.js
getCardMeta.js
index.css
main.jsx
App.jsx
Run the demo app:
npm run dev
# or: yarn dev / pnpm devBuild the demo:
npm run buildLint (recommended):
npm run lintAdd tests with Vitest + React Testing Library (see Roadmap).
-
Create an entry file
src/index.jsthat re-exports your components:export { default as Badge } from './components/Badges/Badge' export { default as Banner } from './components/Banners/Banner' export { default as Card } from './components/Cards/Card' export { default as Testimonial } from './components/Testimonials/Testimonial'
-
Vite library build: configure
vite.config.jswith abuild.libsection sonpm run buildproducesdist/*.jsbundles ready to publish. -
package.json: set
private: false, addmain,module,exports,files: ["dist"], and peerDependencies onreact,react-dom, and Font Awesome packages if you use them. -
(Optional) Add GitHub Actions to build/lint/test on PRs.
Once published:
npm i @your-scope/components-libraryPRs welcome! If you add a component, please include:
- Minimal props with sensible defaults
- A README section + usage example
- Accessibility considerations (focus order, ARIA if needed)
- Unit tests (once testing is set up)
- Convert global CSS to CSS Modules
- Add Storybook for interactive docs
- Add Vitest + React Testing Library
- Improve a11y (keyboard navigation, color contrast)
- Publish to npm under a scope
MIT © 2025 Joaco Pobre.