A deliciously modern design system for building beautiful web applications
A modern, accessible, and customizable design system built with Material-UI and TypeScript. Perfect for building beautiful web applications with a consistent look and feel.
- 🎯 Pixel-Perfect Components: Every component matches our Figma design system exactly
- 🎨 Material Design 3: Built on top of Material-UI with custom theming
- 📱 Responsive Design: Works flawlessly on all devices
- 🎭 Dark Mode Support: Beautiful dark theme included
- 📊 Chart Integration: Ready-to-use chart components
- 🎮 Interactive Components: Rich, interactive UI elements
- 🎯 TypeScript Support: Full type safety and autocompletion
- 📚 Comprehensive Documentation: Detailed guides and examples
# Install the package
npm install puddin-design-system
# Or with yarn
yarn add puddin-design-systemimport { Button } from 'puddin-design-system';
// Filled Button
<Button variant="filled">Click Me! 🎯</Button>
// Outlined Button
<Button variant="outlined">Outline Me! ✨</Button>
// Text Button
<Button variant="text">Just Text! 📝</Button>import { Card } from 'puddin-design-system';
// Elevated Card
<Card variant="elevated">
<CardContent>
<Typography>Floating Card! 🎈</Typography>
</CardContent>
</Card>
// Filled Card
<Card variant="filled">
<CardContent>
<Typography>Solid Card! 🎨</Typography>
</CardContent>
</Card>import { CryptoCard, Swap } from 'puddin-design-system';
// Crypto Card with Chart
<CryptoCard
symbol="BTC"
price="$45,000"
change="+5.2%"
chartData={data}
/>
// Swap Interface
<Swap
fromToken="ETH"
toToken="BTC"
rate="0.05"
chartData={data}
/>Our design system uses a comprehensive token system:
// Primary Colors
theme.palette.primary.main // #6750A4
theme.palette.primary.light // #7F67BE
theme.palette.primary.dark // #4F378B
// Surface Colors
theme.palette.surface.main // #1C1B1F
theme.palette.surface.light // #2D2C31
theme.palette.surface.dark // #0F0E11// 8px Base Unit
theme.spacing(1) // 8px
theme.spacing(2) // 16px
theme.spacing(3) // 24px
theme.spacing(4) // 32px<Button variant="filled" disabled>Disabled 🚫</Button>
<Button variant="filled" loading>Loading... ⏳</Button>
<Button variant="filled" error>Error! ❌</Button><Card variant="elevated" hoverable>
<CardContent>
<Typography>Hover Me! 🎯</Typography>
</CardContent>
</Card>import { createTheme } from 'puddin-design-system';
const theme = createTheme({
palette: {
primary: {
main: '#6750A4',
light: '#7F67BE',
dark: '#4F378B',
},
// ... more customization
},
});Our components are fully responsive and work great on all devices:
// Mobile First
<Box sx={{ width: { xs: '100%', sm: '50%', md: '33%' } }}>
<Card>Responsive Card! 📱</Card>
</Box>-
🎨 Use Design Tokens
// ✅ Good <Box sx={{ p: 2 }}> // Uses theme spacing // ❌ Bad <Box sx={{ padding: '16px' }}> // Hard-coded value
-
📱 Responsive Design
// ✅ Good <Box sx={{ width: { xs: '100%', md: '50%' } }}> // ❌ Bad <Box sx={{ width: '500px' }}>
-
🎭 Theme Integration
// ✅ Good <Box sx={{ bgcolor: 'surface.main' }}> // ❌ Bad <Box sx={{ backgroundColor: '#1C1B1F' }}>
# Clone the repository
git clone https://github.com/your-username/puddin-design-system.git
# Install dependencies
npm install
# Start Storybook
npm run storybook
# Run tests
npm test
# Build the package
npm run buildWe welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
Try our components in the Storybook!
- 🎨 More component variants
- 📱 Mobile-specific components
- 🎭 Advanced theming options
- 📊 More chart types
- 🎮 Interactive examples
- 📚 Enhanced documentation
Need help? Open an issue or reach out to us on Discord!
- Design by [Your Design Team]
- Development by [Your Development Team]
- Icons by [Your Icon Provider]
- Charts by [Your Chart Provider]
Made with ❤️ by the Puddin Team
Try these interactive examples right in your browser! Click the "Edit" button to modify the code.
function ButtonPlayground() {
const [variant, setVariant] = useState('filled');
const [color, setColor] = useState('primary');
const [size, setSize] = useState('medium');
const [disabled, setDisabled] = useState(false);
const [loading, setLoading] = useState(false);
return (
<Stack spacing={2}>
<Button
variant={variant}
color={color}
size={size}
disabled={disabled}
loading={loading}
>
{loading ? 'Loading...' : 'Click Me! 🎯'}
</Button>
<Stack direction="row" spacing={2}>
<Select
value={variant}
onChange={(e) => setVariant(e.target.value)}
label="Variant"
>
<MenuItem value="filled">Filled</MenuItem>
<MenuItem value="outlined">Outlined</MenuItem>
<MenuItem value="text">Text</MenuItem>
</Select>
<Select
value={color}
onChange={(e) => setColor(e.target.value)}
label="Color"
>
<MenuItem value="primary">Primary</MenuItem>
<MenuItem value="secondary">Secondary</MenuItem>
<MenuItem value="success">Success</MenuItem>
</Select>
<Select
value={size}
onChange={(e) => setSize(e.target.value)}
label="Size"
>
<MenuItem value="small">Small</MenuItem>
<MenuItem value="medium">Medium</MenuItem>
<MenuItem value="large">Large</MenuItem>
</Select>
</Stack>
<Stack direction="row" spacing={2}>
<Switch
checked={disabled}
onChange={(e) => setDisabled(e.target.checked)}
label="Disabled"
/>
<Switch
checked={loading}
onChange={(e) => setLoading(e.target.checked)}
label="Loading"
/>
</Stack>
</Stack>
);
}function CardPlayground() {
const [variant, setVariant] = useState('elevated');
const [elevation, setElevation] = useState(1);
const [hoverable, setHoverable] = useState(true);
const [content, setContent] = useState('Card Content');
return (
<Stack spacing={2}>
<Card
variant={variant}
elevation={elevation}
hoverable={hoverable}
sx={{ width: 300 }}
>
<CardContent>
<Typography variant="h6">Interactive Card 🎴</Typography>
<Typography>{content}</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
<Button size="small">Share</Button>
</CardActions>
</Card>
<Stack direction="row" spacing={2}>
<Select
value={variant}
onChange={(e) => setVariant(e.target.value)}
label="Variant"
>
<MenuItem value="elevated">Elevated</MenuItem>
<MenuItem value="filled">Filled</MenuItem>
<MenuItem value="outlined">Outlined</MenuItem>
</Select>
<Slider
value={elevation}
onChange={(e, value) => setElevation(value)}
min={0}
max={5}
marks
valueLabelDisplay="auto"
label="Elevation"
/>
</Stack>
<TextField
value={content}
onChange={(e) => setContent(e.target.value)}
label="Card Content"
fullWidth
/>
<Switch
checked={hoverable}
onChange={(e) => setHoverable(e.target.checked)}
label="Hoverable"
/>
</Stack>
);
}function CryptoPlayground() {
const [token, setToken] = useState('BTC');
const [price, setPrice] = useState('45000');
const [change, setChange] = useState('5.2');
const [chartType, setChartType] = useState('line');
return (
<Stack spacing={2}>
<CryptoCard
symbol={token}
price={`$${price}`}
change={`${change}%`}
chartType={chartType}
chartData={[
{ time: '1h', value: 44000 },
{ time: '2h', value: 44500 },
{ time: '3h', value: 45000 },
{ time: '4h', value: 44800 },
{ time: '5h', value: 45200 },
]}
/>
<Stack direction="row" spacing={2}>
<Select
value={token}
onChange={(e) => setToken(e.target.value)}
label="Token"
>
<MenuItem value="BTC">Bitcoin (BTC)</MenuItem>
<MenuItem value="ETH">Ethereum (ETH)</MenuItem>
<MenuItem value="SOL">Solana (SOL)</MenuItem>
</Select>
<TextField
value={price}
onChange={(e) => setPrice(e.target.value)}
label="Price"
type="number"
/>
<TextField
value={change}
onChange={(e) => setChange(e.target.value)}
label="Change %"
type="number"
/>
</Stack>
<Select
value={chartType}
onChange={(e) => setChartType(e.target.value)}
label="Chart Type"
>
<MenuItem value="line">Line Chart</MenuItem>
<MenuItem value="area">Area Chart</MenuItem>
<MenuItem value="candlestick">Candlestick</MenuItem>
</Select>
</Stack>
);
}function ThemePlayground() {
const [primaryColor, setPrimaryColor] = useState('#6750A4');
const [secondaryColor, setSecondaryColor] = useState('#EF5350');
const [mode, setMode] = useState('dark');
const theme = createTheme({
palette: {
mode,
primary: {
main: primaryColor,
},
secondary: {
main: secondaryColor,
},
},
});
return (
<ThemeProvider theme={theme}>
<Stack spacing={2}>
<Box sx={{ p: 2, bgcolor: 'background.paper' }}>
<Typography variant="h6">Theme Preview</Typography>
<Stack direction="row" spacing={2} sx={{ mt: 2 }}>
<Button variant="filled">Primary Button</Button>
<Button variant="filled" color="secondary">Secondary Button</Button>
</Stack>
</Box>
<Stack direction="row" spacing={2}>
<TextField
type="color"
value={primaryColor}
onChange={(e) => setPrimaryColor(e.target.value)}
label="Primary Color"
/>
<TextField
type="color"
value={secondaryColor}
onChange={(e) => setSecondaryColor(e.target.value)}
label="Secondary Color"
/>
</Stack>
<Switch
checked={mode === 'dark'}
onChange={(e) => setMode(e.target.checked ? 'dark' : 'light')}
label="Dark Mode"
/>
</Stack>
</ThemeProvider>
);
}


