@harshit-wander/component-lib
v1.5.2
Published
WanderOn React component library — themed primitives and page sections built with Tailwind CSS v4.
Readme
@harshit-wander/component-lib
A themed React component library — primitives and full page sections built with Tailwind CSS v4. Zero-runtime styling, SSR-safe for Next.js App Router, ESM + CJS dual-published, fully typed.
Docs: docs/ARCHITECTURE.md explains how the library is structured and how everything fits together. Authoring rules live in
CLAUDE.md.
Install
pnpm add @harshit-wander/component-lib react react-domReplace
pnpmwithnpm installoryarn addif those are your tools.reactandreact-domare peer dependencies — install them in your own project so you don't end up with two copies of React in your bundle.
Requirements
- Node.js
>=20 - React
^18.0.0or^19.0.0
You do not need Tailwind configured in your app — the library ships a precompiled, minified CSS
file (dist/styles.css). You just import it once (below). If your app does use Tailwind, the
library still works; its styles are scoped to its own classes.
Quick start
The library is styled with Tailwind utility classes shipped in one CSS file. Import that file once near the root of your app, then use components anywhere. There is no provider to set up.
Next.js (App Router)
// app/layout.tsx
import '@harshit-wander/component-lib/styles.css'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}Importing the CSS in the root layout means the styles are in the server-rendered HTML — no flash-of-unstyled-content, no client-side style injection, no registry to configure.
Vite / CRA / Remix / plain React
Import the CSS once at your app entry point:
// main.tsx / index.tsx
import '@harshit-wander/component-lib/styles.css'Use components
Every component is named-exported from the package root.
import {
Hero,
CtaBanner,
PackagesCarousel,
Footer,
} from '@harshit-wander/component-lib'
export function HomePage() {
return (
<>
<Hero
variant="reviews"
title="Plan your next trip"
subtitle="Curated group adventures"
backgroundImage="/hero.jpg"
reviews={[/* ... */]}
/>
<PackagesCarousel packages={[/* ... */]} />
<CtaBanner
title="Ready to go?"
ctaLabel="Browse trips"
ctaHref="/packages"
backgroundImage="/cta.jpg"
/>
<Footer companyName="WanderOn" />
</>
)
}Every component forwards a ref, spreads extra props (id, data-*, ARIA, handlers) onto its root
element, and merges any className you pass over its defaults (via tailwind-merge) — so you
can override spacing/layout from the consumer side without fighting specificity.
What's in the box
Primitives (src/components/) — small reusable cards and atoms:
BrandLogo, ContactForm, DestinationCard, EventBanner, EventVideoBanner,
ExpandableValueCard, ExploreCard, FaqExpandable, FeatureCard, GalleryPhoto, LocationCard,
MonthTabs, PackageCard, SectionHeader, TeamInfoCard, TestimonialCard, TripCategoryCard,
WarriorCard.
Sections (src/sections/) — full-width composed page blocks:
BottomNav, BrandsSection, CategoryNavbar, ContactSection, CtaBanner, DestinationsSection,
EventCarousel, ExploreSection, FaqSection, Footer, GallerySection, Hero, HomeHero,
Navbar, OfficesSection, PackagesCarousel, SiteHeader, TeamSection, TestimonialsCarousel,
TextSection, TripsCategorySection, ValuesSection, WarriorsSection, WhyChooseSection.
Theme tokens — a theme object and Theme type are exported from the root, exposing colors,
spacing, radii, fontSizes, fontWeights, shadows, and layout.
Design tokens
All visual values come from a single token set. They are available two ways:
- As Tailwind utility classes (how the components themselves are styled) — e.g.
bg-accent,text-text-muted,gap-md,rounded-md,text-xl. These come from the importedstyles.css. - As a typed JS object, for the rare case you need a raw token value at runtime:
import { theme } from '@harshit-wander/component-lib'
import type { Theme } from '@harshit-wander/component-lib'
theme.colors.primary // '#01AFD1'
theme.spacing.md // '16px'The token object mirrors the @theme definitions in the library's styles.css — they are kept in
sync, so the same names work in both places.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Components render unstyled | The CSS file wasn't imported | Add import '@harshit-wander/component-lib/styles.css' once at your app root. |
| Styles missing only in production | Bundler tree-shook the CSS import | The package sets sideEffects: ["**/*.css"]; ensure your build respects it and don't mark the package side-effect-free in your own config. |
| Invalid hook call at runtime | Two copies of React in the bundle | pnpm why react and dedupe so only one React resolves. |
| My utility classes don't override the component's | Specificity/ordering | Pass them via the component's className prop — tailwind-merge resolves conflicts in your favour. |
Links
- Architecture: docs/ARCHITECTURE.md
- Changelog: CHANGELOG.md
- Repository: https://github.com/harshit-wander/component-lib
- Issues: https://github.com/harshit-wander/component-lib/issues
- npm: https://www.npmjs.com/package/@harshit-wander/component-lib
License
MIT © Harshit Rohilla
