@mdigital_ui/ui
v0.2.5
Published
Modern React component library built with Tailwind CSS v4
Maintainers
Readme
@mdigital/ui
Modern React component library built with Tailwind CSS v4, designed for multi-brand support and maximum customization.
Features
- ✅ 50+ Components - Comprehensive UI component library
- ✅ Tailwind CSS v4 - Modern utility-first CSS framework
- ✅ TypeScript - Full type safety and IntelliSense
- ✅ Dark Mode - Built-in dark mode support
- ✅ Multi-Brand - CSS variable-based theming system
- ✅ Tree-Shakeable - Optimal bundle size with ESM
- ✅ Accessible - WCAG 2.1 AA compliant
- ✅ React 19 - Modern React patterns (no forwardRef)
Installation
npm install @mdigital_ui/uiThat's it! All dependencies and styles are included. Tree-shaking ensures only the components you import end up in your production bundle.
Peer Dependencies
You need to have these in your project:
npm install react react-domQuick Start
1. Import Styles
In your main application entry point (e.g., app/layout.tsx or src/main.tsx):
// Import the base styles
import '@mdigital_ui/ui/styles/base.css'
// Import light theme (default)
import '@mdigital_ui/ui/styles/themes/light.css'
// Optional: Import dark theme for dark mode support
import '@mdigital_ui/ui/styles/themes/dark.css'Or import in your CSS file:
/* app/globals.css or src/index.css */
@import '@mdigital_ui/ui/styles/base.css';
@import '@mdigital_ui/ui/styles/themes/light.css';
/* Optional: Dark mode */
@import '@mdigital_ui/ui/styles/themes/dark.css';2. Use Components
import { Button, Input, Card } from '@mdigital/ui'
function App() {
return (
<Card>
<Input label="Email" placeholder="Enter your email" />
<Button variant="solid" color="primary">
Submit
</Button>
</Card>
)
}Import Patterns
Subpath Imports (Recommended)
import Button from '@mdigital_ui/ui/button'
import Input from '@mdigital_ui/ui/input'
import Table from '@mdigital_ui/ui/table'Tree-shaking works automatically:
- Import only
Button? Only Button code ends up in your bundle - Import
Table? Table + @tanstack/react-table are bundled - Don't import
Carousel? Swiper never touches your bundle
Named Imports
import { Button, Input, Select } from '@mdigital_ui/ui'Both import styles work identically. Use whichever you prefer.
Type Imports
import type { ButtonProps, InputProps } from '@mdigital_ui/ui'Theming & Customization
The UI Kit uses CSS custom properties (variables) for all design tokens, making it easy to customize without touching Tailwind's configuration.
Quick Customization
Create a CSS file to override any design tokens:
/* app/theme.css or src/theme.css */
:root {
/* Brand Colors */
--color-primary: oklch(0.55 0.22 270); /* Purple primary */
--color-primary-hover: oklch(0.50 0.24 270);
--color-accent: oklch(0.75 0.18 45); /* Orange accent */
/* Semantic Colors */
--color-success: oklch(0.65 0.20 140);
--color-error: oklch(0.60 0.25 20);
/* Component Sizing */
--button-height-md: 2.5rem;
--input-height-md: 2.5rem;
--radius-md: 0.5rem;
/* Typography */
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--text-base: 1rem;
}Then import it after the UI Kit styles:
import '@mdigital_ui/ui/styles/base.css'
import '@mdigital_ui/ui/styles/themes/light.css'
import './theme.css' // Your customizationsAvailable Variables
/* Brand Colors */
--color-primary
--color-primary-hover
--color-primary-active
--color-primary-foreground
--color-secondary
--color-secondary-hover
--color-secondary-active
--color-secondary-foreground
--color-accent
--color-accent-hover
--color-accent-active
--color-accent-foreground
/* Semantic Colors */
--color-success
--color-success-hover
--color-success-active
--color-error
--color-error-hover
--color-error-active
--color-warning
--color-warning-hover
--color-warning-active
--color-info
--color-info-hover
--color-info-active
/* Backgrounds & Surfaces */
--color-background
--color-background-secondary
--color-surface
--color-border
--color-border-primary
/* Text Colors */
--color-text-primary
--color-text-secondary
--color-text-muted
/* Grayscale */
--color-gray-50 through --color-gray-950
--color-white
--color-black/* Button Sizes */
--button-height-xs: 1.75rem
--button-height-sm: 2rem
--button-height-md: 2.25rem
--button-height-lg: 2.75rem
--button-padding-x-xs: 0.5rem
--button-padding-x-sm: 0.75rem
--button-padding-x-md: 0.875rem
--button-padding-x-lg: 1.25rem
/* Input Sizes */
--input-height-xs: 1.75rem
--input-height-sm: 2rem
--input-height-md: 2.25rem
--input-height-lg: 2.75rem
--input-padding-x-xs through --input-padding-x-lg
/* Select Sizes */
--select-height-xs through --select-height-lg
--select-padding-x-xs through --select-padding-x-lg
/* Checkbox/Radio Sizes */
--checkbox-size-xs: 0.875rem
--checkbox-size-sm: 1rem
--checkbox-size-md: 1.125rem
--checkbox-size-lg: 1.375rem
/* Switch Sizes */
--switch-width-xs through --switch-width-lg
--switch-height-xs through --switch-height-lg
/* Spacing Scale */
--spacing-0 through --spacing-12/* Font Families */
--font-sans: ui-sans-serif, system-ui, sans-serif
--font-mono: ui-monospace, 'SF Mono', monospace
/* Font Sizes */
--text-xs: 0.75rem
--text-sm: 0.875rem
--text-base: 0.9rem
--text-lg: 1.125rem
/* Font Weights */
--font-weight-normal: 400
--font-weight-medium: 500
--font-weight-semibold: 600
--font-weight-bold: 700
/* Label Sizes */
--label-font-size-xs through --label-font-size-lg/* Border Radius */
--radius-none: 0px
--radius-sm: 0.25rem
--radius-md: 0.375rem
--radius-lg: 0.5rem
--radius-xl: 0.625rem
--radius-2xl: 0.75rem
--radius-3xl: 1rem
--radius-full: 9999px
/* Shadows */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05)
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1)
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1)
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1)
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25)
/* Transitions */
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1)
--transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1)
--transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1)
/* Z-Index Layers */
--z-dropdown: 1000
--z-sticky: 1020
--z-modal: 1040
--z-popover: 1050
--z-tooltip: 1060Example: Custom Brand Theme
See examples/custom-theme.css for a complete template with all available variables and comments.
Quick example:
/* brand-theme.css */
:root {
/* Acme Corp Brand Colors */
--color-primary: oklch(0.60 0.20 200); /* Acme Blue */
--color-primary-hover: oklch(0.55 0.22 200);
--color-secondary: oklch(0.55 0.15 320); /* Acme Purple */
--color-accent: oklch(0.75 0.18 160); /* Acme Green */
/* Rounded Everything */
--radius-sm: 0.5rem;
--radius-md: 0.75rem;
--radius-lg: 1rem;
/* Larger Buttons */
--button-height-sm: 2.25rem;
--button-height-md: 2.75rem;
--button-height-lg: 3.25rem;
/* Custom Font */
--font-sans: 'Poppins', ui-sans-serif, system-ui, sans-serif;
}Dark Mode
Enable dark mode by adding the dark class to your HTML element:
// Example with state
const [isDark, setIsDark] = useState(false)
<html className={isDark ? 'dark' : ''}>
<body>{children}</body>
</html>All components automatically adapt to dark mode via CSS variables.
Creating Custom Themes
Create your own theme file:
/* my-brand-theme.css */
:root {
--color-primary: oklch(0.6 0.2 150); /* Green */
--color-secondary: oklch(0.5 0.15 30); /* Orange */
--color-background: oklch(98% 0 0);
--color-text-primary: oklch(20% 0 0);
}Components
Core Components
- Button - Primary action buttons with variants
- Input - Form input with validation
- Select - Dropdown selection
- Checkbox - Toggle option
- Radio - Single selection
- Switch - Toggle switch
- Textarea - Multi-line text input
Display Components
- Card - Content container
- Badge - Status indicator
- Tag - Label chip
- Avatar - User profile image
- Skeleton - Loading placeholder
- Empty - Empty state
- Spinner - Loading indicator
Navigation
- Tabs - Tabbed navigation
- Breadcrumbs - Hierarchical navigation
- Pagination - Page navigation
- Dropdown - Dropdown menu
Feedback
- Modal - Dialog overlay
- Drawer - Side panel
- Tooltip - Hover information
- Popover - Contextual popup
- Notification - Toast message
- Progress - Progress indicator
Data Display
- Table - Data table with sorting
- Descriptions - Key-value pairs
- Tree - Hierarchical data
- Timeline - Event timeline
Advanced
- DatePicker - Date selection
- Upload - File upload
- Transfer - Dual list selector
- Cascader - Cascading selection
- TreeSelect - Tree selection
See full component list and documentation
Customization
Three Levels of Customization
1. CSS Variables (Global)
:root {
--color-primary: oklch(0.55 0.22 270);
}2. className Prop (Instance)
<Button className="shadow-lg hover:scale-105">
Custom Button
</Button>3. Wrapper Components (New Variants)
function GlassButton({ className, ...props }) {
return (
<Button
className={cn(
'bg-white/10 backdrop-blur-md border-white/20',
className
)}
{...props}
/>
)
}TypeScript
Full TypeScript support with auto-generated types:
import type { ButtonProps } from '@mdigital/ui'
const MyButton: React.FC<ButtonProps> = (props) => {
return <Button {...props} />
}Accessibility
All components follow WCAG 2.1 AA standards:
- ✅ Keyboard navigation
- ✅ Screen reader support
- ✅ Focus indicators
- ✅ ARIA attributes
- ✅ Color contrast compliance
Bundle Size
Optimized for minimal bundle impact:
- Single component: ~3-8kb (gzipped)
- Full package (tree-shaken): ~20-40kb (gzipped)
- CSS variables: ~2kb (gzipped)
Browser Support
- Chrome (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Edge (latest 2 versions)
Documentation
- Storybook - Interactive component playground
- Theming Guide - Detailed theming documentation
- Migration Guide - Upgrade guides
Contributing
Internal contributions welcome! Please follow the contribution guidelines.
License
MIT © MDigital
Support
For issues or questions:
- Internal Slack: #design-system
- Issues: GitHub Issues
Made with ❤️ by the MDigital Design System Team
