@latte-macchiat-io/latte-vanilla-components
v0.0.553
Published
Beautiful components for amazing projects, with a touch of Vanilla π₯€
Downloads
1,582
Readme
π₯€ Latte Vanilla Components 
Beautiful, type-safe React components powered by Vanilla Extract CSS for amazing projects, with a touch of Vanilla π₯€
Intended for internal use by the π©βπ»π§βπ» latte-macchiat.io team, we can't offer official support, but feel free to reach out with questions, feedback or project ideas!
β¨ Features
- π¨ Professional Theme System - Light/dark themes with full customization
- π Zero Runtime CSS-in-JS - Vanilla Extract for optimal performance
- π± Responsive Design - Mobile-first, accessible components
- π Type Safety - Full TypeScript support throughout
- β‘ Developer Experience - Hot reloading, IntelliSense, documentation
- π― Production Ready - Optimized builds, minimal bundle size
π€ Philosophy
This library is shipped as raw code (ESM + TypeScript) to be compiled in your project, allowing full customization and tree-shaking. It is not a pre-built design system, but rather a set of building blocks to create your own unique designs.
You will need to set up Vanilla Extract in your build system (Next.js, Vite, etc.) to use this library.
π¦ Installation
npm install @latte-macchiat-io/latte-vanilla-components
# or
pnpm add @latte-macchiat-io/latte-vanilla-components
# or
yarn add @latte-macchiat-io/latte-vanilla-componentsπ Quick Start
1. Set up your theme (choose one approach):
Option A: Reuse default theme
// src/styles/theme.css.ts
import { createDarkTheme, createLightTheme } from "@latte-macchiat-io/latte-vanilla-components";
// Create and apply the default light theme (minimal setup)
createLightTheme();
// Optional: enable dark theme support
createDarkTheme();Option B: Customize partially themes
// src/styles/theme.css.ts
import { createDarkTheme, createLightTheme } from '@latte-macchiat-io/latte-vanilla-components';
// Override only specific properties in light and dark themes
createLightTheme({
colors: {
background: '#f0f0f0', // Custom light background color
text: '#333333', // Custom light text color
},
fonts: {
body: 'Arial, sans-serif', // Custom font for body
},
fontSizes: {
md: '18px', // Custom medium font size
},
});
// Optional: customize dark theme as well
createDarkTheme({
colors: {
background: '#121212', // Custom dark background color
text: '#e0e0e0', // Custom dark text color
},
});Option C: Full Custom Theme (= contract redefinition)
// src/styles/theme.css.ts
import { createGlobalTheme } from '@vanilla-extract/css';
import { themeContract } from '@latte-macchiat-io/latte-vanilla-components';
createGlobalTheme(':root', themeContract, {
colors: {
primary: '#FF7377',
background: '#ffffff',
text: '#000000',
// ... define all colors
},
space: {
xs: '4px',
sm: '8px',
md: '16px',
// ... define all spacing
},
// ... define all theme properties
});
createGlobalTheme('html[data-theme="dark"]', themeContract, {
colors: {
primary: '#FF7377',
background: '#1a1a1a',
text: '#ffffff',
// ... dark theme colors
},
// ... same structure as light theme
});2. Import your theme globally:
// src/app/layout.tsx (Next.js)
import '../styles/theme.css';
// src/main.tsx (Vite)
import './styles/theme.css';3. Start using components:
import { Button, Section, Header, Modal } from '@latte-macchiat-io/latte-vanilla-components';
export default function App() {
return (
<Section>
<Header>
<h1>My App</h1>
</Header>
<Button variant="primary" size="large">
Get Started
</Button>
<Modal>
<p>Beautiful, accessible modal content!</p>
</Modal>
</Section>
);
}π¨ Theme Customization
Available Theme Properties
- [ ] TODO @Gaelle
Theme Switching
Add dark mode support:
import { setTheme, toggleTheme } from '@latte-macchiat-io/latte-vanilla-components';
function ThemeToggle() {
return <button onClick={() => toggleTheme()}>Toggle Dark Mode</button>;
}
// Or set specific theme
setTheme('dark'); // Switch to dark
setTheme('light'); // Switch to lightπ§© Available Components
Layout Components
- Section - Content sections with consistent spacing
- Header - App headers with navigation support
- Footer - App footers with links and info
- Main - Main content areas
- Columns - Responsive column layouts
Interactive Components
- Button - Primary, secondary, and variant buttons
- Modal - Accessible modals with animations
- Form - Complete form system with validation
- TextField - Text inputs with labels and validation
- Carousel - Image and content carousels
Content Components
- Video - Responsive video players
- VideoFullWidth - Full-width video backgrounds
- Logo - Responsive logo display
- Icon - Icon system with multiple sizes
- KeyNumber - Highlight important numbers/stats
Navigation Components
- Nav - Primary navigation
- NavSocial - Social media links
- NavLegal - Legal/policy links
- LanguageSwitcher - Multi-language support
Utility Components
- Actions - Action button groups
- ConsentCookie - GDPR cookie consent
π± Responsive Design
All components are mobile-first and responsive:
// Responsive spacing using sprinkles
<Section className={sprinkles({
padding: { mobile: 'md', desktop: 'xl' }
})}>
Content adapts to screen size
</Section>
// Built-in responsive variants
<Button size={{ mobile: 'small', desktop: 'large' }}>
Responsive Button
</Button>π Development
Using with Next.js
// next.config.js
import type { NextConfig } from "next";
import { createVanillaExtractPlugin } from "@vanilla-extract/next-plugin";
const nextConfig: NextConfig = {
/* config options here */
transpilePackages: ['@latte-macchiat-io/latte-vanilla-components']
};
const withVanillaExtract = createVanillaExtractPlugin({
identifiers: process.env.NODE_ENV === 'production' ? 'short' : 'debug',
});
export default withVanillaExtract(nextConfig);
Using with Vite
// vite.config.ts
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
export default {
plugins: [vanillaExtractPlugin()],
optimizeDeps: {
exclude: ['@latte-macchiat-io/latte-vanilla-components'],
},
};π Advanced Usage
Custom Component Styling
import { sprinkles } from '@latte-macchiat-io/latte-vanilla-components';
// Use the sprinkles utility for custom styling
<div
className={sprinkles({
padding: 'lg',
backgroundColor: 'primary',
borderRadius: 'md',
color: 'white',
})}>
Custom styled element
</div>;Extending Components
Create your own custom components using the theme contract and styleOverride for guaranteed specificity:
// src/components/CustomButton/styles.css.ts
import { styleOverride } from '@latte-macchiat-io/latte-vanilla-components/utils/styleOverride';
import { themeContract } from '@latte-macchiat-io/latte-vanilla-components';
export const customButton = styleOverride({
backgroundColor: themeContract.colors.primary,
color: themeContract.colors.background,
padding: `${themeContract.space.md} ${themeContract.space.lg}`,
borderRadius: themeContract.radii.full,
transition: 'all 0.2s ease',
':hover': {
backgroundColor: themeContract.colors.secondary,
},
});// src/components/CustomButton/index.tsx
import { customButton } from './styles.css';
export function CustomButton({ children, ...props }) {
return (
<button className={customButton} {...props}>
{children}
</button>
);
}π― Performance
- Zero Runtime CSS-in-JS - All styles compiled at build time
- Atomic CSS - Reusable utility classes reduce bundle size
- Tree Shaking - Only import components you use
- Optimized Builds - Minimal CSS output in production
π Development & storybook testing
Run Storybook
pnpm run storybookThen open http://localhost:6006 to explore components.
Publishing
Push changes to main branch and GitHub Actions will automatically publish to NPM.
Made with β€οΈ by the Latte team π₯€
