Theming
Customize the appearance of all Dropper components with a simple theming system that allows you to match your brand colors.
Basic Theming
Set a primary color in the DropperProvider:
import { DropperProvider } from '@dropper/react'
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#10b981' }}
>
<App />
</DropperProvider>
Theme Configuration
interface DropperTheme {
primary: string // Primary color (required)
colors?: { // Optional: Custom color shades
primary50?: string
primary100?: string
primary200?: string
primary300?: string
primary400?: string
primary500?: string
primary600?: string
primary700?: string
primary800?: string
primary900?: string
}
}
primary
The main brand color used throughout components:
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#3b82f6' }} // Blue
>
<App />
</DropperProvider>
colors
Optionally provide custom color shades for fine-grained control:
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{
primary: '#10b981',
colors: {
primary50: '#ecfdf5',
primary100: '#d1fae5',
primary200: '#a7f3d0',
primary300: '#6ee7b7',
primary400: '#34d399',
primary500: '#10b981', // Same as primary
primary600: '#059669',
primary700: '#047857',
primary800: '#065f46',
primary900: '#064e3b',
},
}}
>
<App />
</DropperProvider>
Color Shades
If you only provide primary, color shades are auto-generated. The shades are used for:
- 50-200: Light backgrounds, hover states
- 300-400: Borders, secondary elements
- 500: Primary color (buttons, links)
- 600-700: Hover states, active states
- 800-900: Text, dark elements
Preset Themes
Blue (Default)
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#3b82f6' }}
>
<App />
</DropperProvider>
Green
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#10b981' }}
>
<App />
</DropperProvider>
Purple
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#8b5cf6' }}
>
<App />
</DropperProvider>
Red
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#ef4444' }}
>
<App />
</DropperProvider>
Orange
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#f97316' }}
>
<App />
</DropperProvider>
Pink
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#ec4899' }}
>
<App />
</DropperProvider>
Using Theme in Components
useTheme Hook
Access theme values in your components:
import { useTheme } from '@dropper/react'
function CustomButton() {
const theme = useTheme()
return (
<button
style={{
backgroundColor: theme.primary,
color: 'white',
}}
>
Click me
</button>
)
}
ResolvedTheme Interface
interface ResolvedTheme {
primary: string
primary50: string
primary100: string
primary200: string
primary300: string
primary400: string
primary500: string
primary600: string
primary700: string
primary800: string
primary900: string
}
Complete Examples
Brand Color Theme
import { DropperProvider } from '@dropper/react'
function App() {
return (
<DropperProvider
publishableKey={process.env.NEXT_PUBLIC_DROPPER_KEY!}
theme={{ primary: '#FF6B6B' }} // Your brand color
>
<YourApp />
</DropperProvider>
)
}
Dynamic Theme
import { DropperProvider } from '@dropper/react'
import { useState } from 'react'
function App() {
const [theme, setTheme] = useState('#3b82f6')
return (
<div>
<div className="theme-picker">
<button onClick={() => setTheme('#3b82f6')}>Blue</button>
<button onClick={() => setTheme('#10b981')}>Green</button>
<button onClick={() => setTheme('#8b5cf6')}>Purple</button>
</div>
<DropperProvider
publishableKey={process.env.NEXT_PUBLIC_DROPPER_KEY!}
theme={{ primary: theme }}
>
<YourApp />
</DropperProvider>
</div>
)
}
User Preference Theme
import { DropperProvider } from '@dropper/react'
import { useEffect, useState } from 'react'
function App() {
const [theme, setTheme] = useState('#3b82f6')
useEffect(() => {
// Load user's preferred theme
const savedTheme = localStorage.getItem('theme')
if (savedTheme) {
setTheme(savedTheme)
}
}, [])
const updateTheme = (newTheme: string) => {
setTheme(newTheme)
localStorage.setItem('theme', newTheme)
}
return (
<DropperProvider
publishableKey={process.env.NEXT_PUBLIC_DROPPER_KEY!}
theme={{ primary: theme }}
>
<YourApp onThemeChange={updateTheme} />
</DropperProvider>
)
}
Custom Themed Component
import { useTheme } from '@dropper/react'
function ThemedCard({ children }) {
const theme = useTheme()
return (
<div
style={{
border: `2px solid ${theme.primary200}`,
borderRadius: '8px',
padding: '16px',
backgroundColor: theme.primary50,
}}
>
<div
style={{
color: theme.primary700,
fontWeight: 'bold',
marginBottom: '8px',
}}
>
{children}
</div>
</div>
)
}
Gradient Background
import { useTheme } from '@dropper/react'
function GradientHeader() {
const theme = useTheme()
return (
<header
style={{
background: `linear-gradient(135deg, ${theme.primary500} 0%, ${theme.primary700} 100%)`,
color: 'white',
padding: '24px',
}}
>
<h1>My App</h1>
</header>
)
}
CSS Variables
Theme colors are also available as CSS variables:
.custom-element {
background-color: var(--dropper-primary);
border-color: var(--dropper-primary-200);
color: var(--dropper-primary-700);
}
Available variables:
--dropper-primary
--dropper-primary-50
--dropper-primary-100
--dropper-primary-200
--dropper-primary-300
--dropper-primary-400
--dropper-primary-500
--dropper-primary-600
--dropper-primary-700
--dropper-primary-800
--dropper-primary-900
Tailwind Integration
If using Tailwind CSS, extend your theme:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
dropper: {
50: 'var(--dropper-primary-50)',
100: 'var(--dropper-primary-100)',
200: 'var(--dropper-primary-200)',
300: 'var(--dropper-primary-300)',
400: 'var(--dropper-primary-400)',
500: 'var(--dropper-primary-500)',
600: 'var(--dropper-primary-600)',
700: 'var(--dropper-primary-700)',
800: 'var(--dropper-primary-800)',
900: 'var(--dropper-primary-900)',
},
},
},
},
}
Then use in your components:
<div className="bg-dropper-500 text-white">
Themed with Tailwind
</div>
Best Practices
1. Use Brand Colors
Match your brand identity:
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#YOUR_BRAND_COLOR' }}
>
<App />
</DropperProvider>
2. Ensure Contrast
Choose colors with good contrast for accessibility:
// Good: High contrast
theme={{ primary: '#2563eb' }}
// Avoid: Low contrast
theme={{ primary: '#e0e0e0' }}
3. Test Dark Mode
If your app supports dark mode, test theme colors:
const theme = isDarkMode
? { primary: '#60a5fa' } // Lighter for dark mode
: { primary: '#2563eb' } // Darker for light mode
<DropperProvider theme={theme}>
<App />
</DropperProvider>
4. Provide Fallbacks
Always provide a fallback theme:
const userTheme = getUserTheme() || '#3b82f6'
<DropperProvider theme={{ primary: userTheme }}>
<App />
</DropperProvider>
5. Use useTheme for Custom Components
Access theme in custom components:
import { useTheme } from '@dropper/react'
function CustomComponent() {
const theme = useTheme()
return (
<div style={{ color: theme.primary }}>
Themed content
</div>
)
}
Color Accessibility
Ensure your theme colors meet WCAG accessibility standards:
Contrast Ratios
- Normal text: Minimum 4.5:1 contrast ratio
- Large text: Minimum 3:1 contrast ratio
- UI components: Minimum 3:1 contrast ratio
Testing Tools
- WebAIM Contrast Checker
- Coolors Contrast Checker
- Chrome DevTools Accessibility Panel
TypeScript Support
Theme types are fully typed:
import type { DropperTheme, ResolvedTheme } from '@dropper/react'
const theme: DropperTheme = {
primary: '#3b82f6',
colors: {
primary500: '#3b82f6',
primary600: '#2563eb',
},
}
<DropperProvider theme={theme}>
<App />
</DropperProvider>
Default Theme
If no theme is provided, Dropper uses a default blue theme:
{
primary: '#3b82f6', // Tailwind blue-500
primary50: '#eff6ff',
primary100: '#dbeafe',
primary200: '#bfdbfe',
primary300: '#93c5fd',
primary400: '#60a5fa',
primary500: '#3b82f6',
primary600: '#2563eb',
primary700: '#1d4ed8',
primary800: '#1e40af',
primary900: '#1e3a8a',
}
Affected Components
Theming affects all Dropper components:
- FileUpload: Upload button, progress bars, borders
- FileList: Selection highlights, action buttons
- FolderBrowser: Active folder, hover states
- MediaLibrary: All UI elements
- Buttons: Primary buttons, links
- Modals: Headers, action buttons
- Progress: Progress bars, status indicators
Next Steps
- Provider Setup - Configure the provider
- Media Library - Complete media management
- useDropper Hook - Access theme in components