@vantara-ui/ui
v0.4.2
Published
Production-ready React + TypeScript UI component library
Readme
Consuming Vantara-UI Component Library
A complete guide for integrating the @vantara-ui/ui component library into your React + TypeScript applications.
Table of Contents
- Installation
- Quick Start
- Tailwind CSS Integration
- Button Component Examples
- Theming & Customization
- Version Pinning
- TypeScript Support
- Troubleshooting
Installation
Prerequisites
- Node.js 18+
- React 18+
- TypeScript 5.0+
- Tailwind CSS 3.0+
Step 1: Install the Library
npm install @vantara-ui/uiOr with yarn:
yarn add @vantara-ui/uiOr with pnpm:
pnpm add @vantara-ui/uiStep 2: Verify Installation
# Check it installed correctly
npm list @vantara-ui/ui
# Should show:
# └── @vantara-ui/[email protected]Quick Start
1. Import Global Styles
In your application entry point (e.g., src/main.tsx or src/index.tsx):
// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// Import vantara-ui global styles FIRST
import '@vantara-ui/ui/dist/globals.css'
// Then your app
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)⚠️ Important: Import vantara-ui styles before your app styles so you can override them if needed.
2. Import Components
// src/App.tsx
import { Button } from '@vantara-ui/ui'
export default function App() {
return (
<div className="p-8">
<h1>My App with Vantara-UI</h1>
<Button variant="primary">Click me</Button>
</div>
)
}3. Run Your App
npm run devComponents should render with vantara-ui styling! ✅
Tailwind CSS Integration
Prerequisites
Your project must have Tailwind CSS configured. If you don't have it:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -pStep 1: Update tailwind.config.ts
Configure Tailwind to use vantara-ui tokens:
// tailwind.config.ts
import type { Config } from 'tailwindcss'
import vantaraConfig from '@vantara-ui/ui/dist/tailwind.config'
export default {
// Start with vantara-ui config as base
...vantaraConfig,
// Extend with your app-specific styles
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
// Important: include vantara-ui components
'./node_modules/@vantara-ui/ui/dist/**/*.{js,mjs}',
],
theme: {
extend: {
// Add your custom colors, fonts, etc. here
colors: {
'brand': '#your-color',
},
fontFamily: {
'sans': ['Your Font', 'sans-serif'],
},
},
},
plugins: [],
} satisfies ConfigStep 2: Update globals.css
Make sure your global CSS includes Tailwind directives:
/* src/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Your custom styles can go here */Step 3: Verify Setup
npm run devTailwind utilities should be available everywhere:
<div className="p-4 bg-primary text-white rounded-lg">
// This works! ✅
</div>Button Component Examples
Basic Usage
import { Button } from '@vantara-ui/ui'
export function MyComponent() {
return (
<div className="space-y-4">
{/* Primary button (compact) */}
<Button variant="primary">
Next Step
</Button>
{/* Secondary button (large) */}
<Button variant="secondary">
Sign Up
</Button>
</div>
)
}With Click Handler
import { Button } from '@vantara-ui/ui'
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>Count: {count}</p>
<Button
variant="primary"
onClick={() => setCount(count + 1)}
>
Increment
</Button>
</div>
)
}Customizing Colors
import { Button } from '@vantara-ui/ui'
export function CustomButtons() {
return (
<div className="space-y-4">
{/* Red button */}
<Button
variant="primary"
style={{
backgroundColor: '#FF6B6B',
color: '#FFFFFF'
}}
>
Delete
</Button>
{/* Green button */}
<Button
variant="secondary"
style={{
backgroundColor: '#51CF66',
color: '#FFFFFF'
}}
>
Save
</Button>
{/* Blue button */}
<Button
variant="primary"
style={{
backgroundColor: '#339AF0',
color: '#FFFFFF'
}}
>
Download
</Button>
</div>
)
}Customizing Fonts
import { Button } from '@vantara-ui/ui'
export function StyledButtons() {
return (
<div className="space-y-4">
{/* Bold, larger text */}
<Button
variant="primary"
className="font-bold text-lg"
>
Bold Button
</Button>
{/* Uppercase, wider spacing */}
<Button
variant="secondary"
className="uppercase tracking-wider"
>
Uppercase Button
</Button>
{/* Custom font combo */}
<Button
variant="primary"
className="font-bold text-lg tracking-wide"
>
Styled Button
</Button>
</div>
)
}Form Integration
import { Button } from '@vantara-ui/ui'
import { useState } from 'react'
export function LoginForm() {
const [email, setEmail] = useState('')
const [isLoading, setIsLoading] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setIsLoading(true)
try {
// Your login logic here
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email }),
})
// Handle response
} finally {
setIsLoading(false)
}
}
return (
<form onSubmit={handleSubmit} className="space-y-4">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="[email protected]"
className="w-full px-4 py-2 border rounded-lg"
/>
<Button
type="submit"
variant="secondary"
disabled={isLoading || !email}
className="w-full"
style={{
backgroundColor: '#2196F3',
color: '#FFFFFF'
}}
>
{isLoading ? 'Signing In...' : 'Sign In'}
</Button>
</form>
)
}Button Group
import { Button } from '@vantara-ui/ui'
export function ButtonGroup() {
return (
<div className="flex gap-4">
<Button
variant="primary"
style={{ backgroundColor: '#666' }}
>
Cancel
</Button>
<Button
variant="secondary"
style={{ backgroundColor: '#2196F3' }}
className="font-bold"
>
Continue
</Button>
</div>
)
}Disabled State
import { Button } from '@vantara-ui/ui'
import { useState } from 'react'
export function ConditionalButton() {
const [isFormValid, setIsFormValid] = useState(false)
return (
<Button
variant="secondary"
disabled={!isFormValid}
style={{
backgroundColor: isFormValid ? '#51CF66' : '#999',
color: '#FFFFFF'
}}
>
{isFormValid ? 'Save Changes' : 'Complete Form First'}
</Button>
)
}Accessibility Example
import { Button } from '@vantara-ui/ui'
export function AccessibleButtons() {
return (
<div className="space-y-4">
{/* Label for icon button */}
<Button
variant="primary"
aria-label="Close dialog"
>
✕
</Button>
{/* Toggle button with pressed state */}
<Button
variant="ghost"
aria-pressed={false}
>
Toggle Feature
</Button>
{/* Button with description */}
<Button
variant="secondary"
aria-describedby="submit-help"
>
Submit Form
</Button>
<p id="submit-help" className="text-sm text-gray-600">
Submit requires all fields to be filled
</p>
</div>
)
}Theming & Customization
Using Design Tokens
Vantara-ui includes design tokens you can use directly:
import { tokens } from '@vantara-ui/ui'
export function TokenExample() {
return (
<div
style={{
padding: tokens.spacing[4], // 16px
backgroundColor: tokens.colors.primary,
borderRadius: tokens.radius.md, // 8px
fontSize: tokens.typography.body.md.size,
}}
>
Styled with tokens
</div>
)
}CSS Variables
Vantara-ui exports CSS variables you can use in your CSS:
/* src/custom.css */
.my-component {
padding: var(--spacing-4);
background-color: var(--color-primary);
border-radius: var(--radius-md);
color: var(--color-text-inverse);
}Dark Mode
Enable dark mode by adding the dark class to your root element:
// src/App.tsx
import { useState } from 'react'
export default function App() {
const [isDark, setIsDark] = useState(false)
return (
<div className={isDark ? 'dark' : ''}>
<button onClick={() => setIsDark(!isDark)}>
Toggle Theme
</button>
{/* Components automatically adjust colors */}
<YourComponents />
</div>
)
}Or detect system preference:
import { useEffect, useState } from 'react'
export default function App() {
const [isDark, setIsDark] = useState(
window.matchMedia('(prefers-color-scheme: dark)').matches
)
useEffect(() => {
const media = window.matchMedia('(prefers-color-scheme: dark)')
const handleChange = (e: MediaQueryListEvent) => setIsDark(e.matches)
media.addEventListener('change', handleChange)
return () => media.removeEventListener('change', handleChange)
}, [])
return (
<div className={isDark ? 'dark' : ''}>
<YourComponents />
</div>
)
}Global Color Override
Override colors globally by setting CSS variables:
/* src/globals.css */
:root {
--color-primary: #your-brand-color;
--color-secondary: #your-secondary-color;
}
@media (prefers-color-scheme: dark) {
:root {
--color-primary: #your-dark-primary;
--color-secondary: #your-dark-secondary;
}
}Version Pinning
Recommended Approach: Minor Version Pinning
In your package.json:
{
"dependencies": {
"@vantara-ui/ui": "^0.1.0"
}
}What this means:
- ✅ Installs: 0.1.0, 0.1.1, 0.2.0, etc.
- ❌ Won't install: 1.0.0 (breaking changes)
- ✅ Safe for minor/patch updates
- ✅ Get bug fixes automatically
Strict Version Pinning (Most Conservative)
For production apps, use exact pinning:
{
"dependencies": {
"@vantara-ui/ui": "0.1.0"
}
}What this means:
- ✅ Installs only: 0.1.0
- ❌ Won't auto-update to 0.1.1 or 0.2.0
- ✅ Ensures consistency across team
- ❌ Requires manual updates
Check for Updates
# See available updates
npm outdated
# Shows:
# Package Current Wanted Latest Location
# @vantara-ui/ui 0.1.0 0.1.1 0.2.0 node_modules/@vantara-ui/ui
# Update to latest compatible version
npm update @vantara-ui/ui
# Update to specific version
npm install @vantara-ui/[email protected]
# Update to latest (including breaking)
npm install @vantara-ui/ui@latestSecurity Updates
Always install security patches:
# Check for security vulnerabilities
npm audit
# Fix vulnerabilities automatically
npm audit fix
# Fix even if it breaks compatibility (use with caution)
npm audit fix --forceTypeScript Support
Full Type Safety
Vantara-ui is fully typed with TypeScript:
import { Button, type ButtonProps } from '@vantara-ui/ui'
// Get autocomplete for all props
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
console.log('Clicked!')
}
export function MyComponent() {
return (
<Button
variant="primary" // ✅ Typed: 'primary' | 'secondary'
onClick={handleClick} // ✅ Typed correctly
disabled={false} // ✅ Typed as boolean
>
Click
</Button>
)
}Component Props Types
Reference component props in your code:
import type { ButtonProps } from '@vantara-ui/ui'
// Create wrapper with stricter props
export function WarningButton(props: Omit<ButtonProps, 'variant'>) {
return (
<Button
variant="primary"
style={{ backgroundColor: '#FF6B6B' }}
{...props}
/>
)
}Extend Component Types
Create custom component types:
import type { ButtonProps } from '@vantara-ui/ui'
import { Button } from '@vantara-ui/ui'
interface CustomButtonProps extends ButtonProps {
size?: 'compact' | 'normal' | 'spacious'
}
export function CustomButton({ size = 'normal', ...props }: CustomButtonProps) {
const sizeClass = {
compact: 'px-2 py-1',
normal: 'px-4 py-2',
spacious: 'px-6 py-3',
}[size]
return (
<Button
className={sizeClass}
{...props}
/>
)
}Project Structure
Recommended organization for consuming vantara-ui:
my-dashboard/
├── src/
│ ├── components/
│ │ ├── Button/ # Custom button wrapper (optional)
│ │ │ └── index.tsx
│ │ ├── Header/
│ │ ├── Sidebar/
│ │ └── Dashboard/
│ ├── pages/
│ │ ├── Home.tsx
│ │ └── Settings.tsx
│ ├── styles/
│ │ ├── globals.css # Include vantara-ui styles here
│ │ └── custom.css
│ ├── main.tsx # Import vantara-ui styles first
│ ├── App.tsx
│ └── index.tsx
├── package.json
├── tailwind.config.ts # Extend with vantara-ui config
├── tsconfig.json
└── vite.config.tsComplete Setup Example
Full App Example
// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// Import vantara-ui styles first
import '@vantara-ui/ui/dist/globals.css'
// Then your styles
import './styles/globals.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)// src/App.tsx
import { useState } from 'react'
import { Button } from '@vantara-ui/ui'
export default function App() {
const [isDark, setIsDark] = useState(false)
return (
<div className={isDark ? 'dark' : ''}>
<header className="bg-bg-primary p-4">
<h1 className="text-heading-lg text-text-primary">
My Dashboard
</h1>
</header>
<main className="p-8 space-y-6">
<div>
<h2 className="text-heading-md text-text-primary mb-4">
Welcome!
</h2>
<div className="flex gap-4">
<Button variant="primary">Get Started</Button>
<Button variant="secondary">Learn More</Button>
</div>
</div>
<div>
<Button
variant="ghost"
onClick={() => setIsDark(!isDark)}
>
{isDark ? '☀️ Light Mode' : '🌙 Dark Mode'}
</Button>
</div>
</main>
</div>
)
}// tailwind.config.ts
import type { Config } from 'tailwindcss'
import vantaraConfig from '@vantara-ui/ui/dist/tailwind.config'
export default {
...vantaraConfig,
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
'./node_modules/@vantara-ui/ui/dist/**/*.{js,mjs}',
],
} satisfies ConfigTroubleshooting
Styles Not Applied
Problem: Components render but styles are missing
Solutions:
Verify import order - vantara-ui styles must come first:
import '@vantara-ui/ui/dist/globals.css' // FIRST import './index.css' // SECONDCheck Tailwind config includes vantara-ui:
content: [ './node_modules/@vantara-ui/ui/dist/**/*.{js,mjs}', ]Verify
postcss.config.jsincludes Tailwind:export default { plugins: { tailwindcss: {}, autoprefixer: {}, }, }
TypeScript Errors
Problem: TypeScript can't find vantara-ui types
Solution:
# Reinstall package to get types
npm reinstall @vantara-ui/ui
# Or manually check node_modules
ls node_modules/@vantara-ui/ui/dist
# Should contain: *.d.ts filesDark Mode Not Working
Problem: Dark mode colors don't apply
Solutions:
Add dark class to root element:
<div className={isDark ? 'dark' : ''}> {/* Content */} </div>Verify Tailwind config has dark mode:
export default { darkMode: 'class', // Important! // ... } satisfies Config
Bundle Size Too Large
Problem: App bundle includes unused vantara-ui code
Solutions:
Only import what you use:
// ❌ Don't do this import * as VantaraUI from '@vantara-ui/ui' // ✅ Do this import { Button } from '@vantara-ui/ui'Verify tree-shaking is enabled:
// vite.config.ts export default { build: { rollupOptions: { output: { manualChunks: undefined, }, }, }, }
CSS Variables Not Available
Problem: CSS variables like var(--color-primary) don't work
Solution: Ensure global styles are imported:
// Must be imported somewhere
import '@vantara-ui/ui/dist/globals.css'Then use in CSS:
.my-component {
color: var(--color-primary);
padding: var(--spacing-4);
}Support & Resources
- GitHub: https://github.com/vantara/vantara-ui
- npm: https://www.npmjs.com/package/@vantara-ui/ui
- Issues: https://github.com/vantara/vantara-ui/issues
- Discussions: https://github.com/vantara/vantara-ui/discussions
What's Next?
Now that you've installed vantara-ui:
- ✅ Explore other components as they're released
- ✅ Customize tokens and theme for your brand
- ✅ Create wrapper components for your specific needs
- ✅ Set up CI/CD for your app
- ✅ Monitor for library updates
Quick Reference
// Install
npm install @vantara-ui/ui
// Import styles
import '@vantara-ui/ui/dist/globals.css'
// Import components
import { Button } from '@vantara-ui/ui'
// Use components
<Button variant="primary">Click me</Button>
// Customize
<Button
variant="secondary"
style={{ backgroundColor: '#FF6B6B' }}
className="font-bold text-lg"
>
Custom Button
</Button>
// Dark mode
<div className="dark">
{/* Components adapt automatically */}
</div>Happy building! 🚀
