UNPKG

muspe-cli

Version:

MusPE Advanced Framework v2.1.3 - Mobile User-friendly Simple Progressive Engine with Enhanced CLI Tools, Specialized E-Commerce Templates, Material Design 3, Progressive Enhancement, Mobile Optimizations, Performance Analysis, and Enterprise-Grade Develo

720 lines (593 loc) 15.5 kB
# MusPE UI Components 📱 A complete mobile-first UI component library for the MusPE Framework. Built with modern web standards and optimized for touch interfaces. ## 🎯 Features - **📱 Mobile-First**: Designed specifically for mobile and touch devices - **🎨 Modern Design**: Clean, minimalist design based on Material Design and iOS principles - **⚡ Performant**: Optimized for mobile performance with efficient rendering - **🔧 Customizable**: Extensive customization options and CSS variables - **♿ Accessible**: Built with accessibility in mind - **🌙 Dark Mode**: Automatic dark mode support - **📐 Responsive**: Adaptive layouts for all screen sizes - **👆 Touch-Friendly**: Optimized for touch interactions and gestures - **🔄 Reactive**: Integrates seamlessly with MusPE's reactive system ## 📦 Installation MusPE UI components are included with the MusPE Framework v2.0+: ```bash npm install -g muspe-cli@2.0.0 ``` Create a new project with UI components: ```bash muspe create my-app cd my-app ``` ## 🚀 Quick Start ### Import Components ```javascript // Import all components import MusPEUI from './src/ui/index.js'; // Or import individual components import { Button, Input, Card, Modal } from './src/ui/index.js'; ``` ### Include CSS ```html <!-- Include MusPE UI CSS --> <link rel="stylesheet" href="./src/ui/muspe-ui.css"> ``` ### Basic Usage ```javascript // Create a button const button = new MusPEUI.Button({ text: 'Click me!', variant: 'primary', callbacks: { onClick: () => console.log('Button clicked!') } }); // Add to DOM document.body.appendChild(button.render()); ``` ## 📚 Components ### 🔘 Button Versatile button component with multiple variants and states. ```javascript const button = new Button({ text: 'Primary Button', variant: 'primary', // primary, secondary, outline, ghost, danger size: 'md', // sm, md, lg, xl icon: '⭐', iconPosition: 'left', // left, right loading: false, disabled: false, fullWidth: false, hapticFeedback: true, callbacks: { onClick: (event) => { console.log('Button clicked!'); } } }); ``` **Methods:** - `setText(text)` - Update button text - `setLoading(loading)` - Toggle loading state - `setDisabled(disabled)` - Toggle disabled state ### 📝 Input Modern input field with validation and multiple variants. ```javascript const input = new Input({ type: 'text', // text, email, password, number, tel, url, search label: 'Full Name', placeholder: 'Enter your name', value: '', variant: 'outline', // outline, filled, underline size: 'md', // sm, md, lg icon: '👤', iconPosition: 'left', clearable: true, required: true, maxLength: 50, callbacks: { onInput: (value, event) => console.log('Input:', value), onChange: (value, event) => console.log('Changed:', value), onFocus: (event) => console.log('Focused'), onBlur: (event) => console.log('Blurred') } }); ``` **Methods:** - `setValue(value)` - Set input value - `getValue()` - Get current value - `setError(message)` - Show error message - `setSuccess(success)` - Show success state - `focus()` - Focus the input - `setDisabled(disabled)` - Toggle disabled state ### 🃏 Card Flexible card component for displaying content. ```javascript const card = new Card({ title: 'Card Title', subtitle: 'Card subtitle', content: 'Card content goes here...', image: 'path/to/image.jpg', variant: 'elevated', // elevated, outlined, filled clickable: true, padding: 'default', // none, sm, default, lg actions: [ { text: 'Action 1', icon: '❤️', callback: () => console.log('Action 1') }, { text: 'Action 2', callback: () => console.log('Action 2') } ], callbacks: { onClick: () => console.log('Card clicked'), onActionClick: (action, index) => console.log('Action clicked', action) } }); ``` **Methods:** - `setTitle(title)` - Update card title - `setContent(content)` - Update card content - `setImage(image)` - Update card image ### 🪟 Modal Full-featured modal dialog component. ```javascript const modal = new Modal({ title: 'Modal Title', content: 'Modal content...', size: 'md', // sm, md, lg, xl, full closable: true, closeOnBackdrop: true, closeOnEscape: true, showHeader: true, showFooter: true, animation: 'slideUp', // slideUp, slideDown, fade, zoom footerActions: [ { text: 'Cancel', variant: 'secondary', callback: () => console.log('Cancelled') }, { text: 'Confirm', variant: 'primary', callback: () => console.log('Confirmed') } ], callbacks: { onOpen: () => console.log('Modal opened'), onClose: () => console.log('Modal closed') } }); // Show modal modal.render(); modal.open(); ``` **Methods:** - `open()` - Show the modal - `close()` - Hide the modal - `setContent(content)` - Update modal content - `setTitle(title)` - Update modal title ### 📱 Action Sheet iOS-style bottom sheet for actions. ```javascript const actionSheet = new ActionSheet({ title: 'Choose Action', message: 'Select one of the options below', actions: [ { text: 'Camera', icon: '📷', callback: () => console.log('Camera') }, { text: 'Photo Library', icon: '🖼️', callback: () => console.log('Photos') }, { text: 'Delete', icon: '🗑️', destructive: true, callback: () => console.log('Delete') } ], cancelButton: 'Cancel', callbacks: { onOpen: () => console.log('Action sheet opened'), onClose: () => console.log('Action sheet closed'), onAction: (action, index) => console.log('Action selected', action) } }); actionSheet.render(); actionSheet.open(); ``` ### 🧭 Navbar Mobile navigation bar component. ```javascript const navbar = new Navbar({ title: 'App Title', backButton: true, searchButton: true, menuButton: false, theme: 'light', // light, dark, auto fixed: true, transparent: false, shadow: true, actions: [ { icon: '⚙️', callback: () => console.log('Settings') } ], callbacks: { onBack: () => history.back(), onSearch: () => console.log('Search'), onMenu: () => console.log('Menu') } }); ``` **Methods:** - `setTitle(title)` - Update navbar title - `setTheme(theme)` - Change theme - `show()` - Show navbar - `hide()` - Hide navbar ### 🔧 Toolbar Bottom toolbar/tab bar component. ```javascript const toolbar = new Toolbar({ position: 'bottom', // top, bottom theme: 'light', activeIndex: 0, items: [ { icon: { active: '🏠', inactive: '🏡' }, label: 'Home' }, { icon: { active: '🔍', inactive: '🔎' }, label: 'Search' }, { icon: { active: '❤️', inactive: '🤍' }, label: 'Favorites' } ], badge: { 2: '5' // Badge on third item }, callbacks: { onItemClick: (index, item) => { console.log('Tab clicked:', index, item.label); } } }); ``` **Methods:** - `setActive(index)` - Set active tab - `setBadge(index, value)` - Update badge - `updateItems(items)` - Update toolbar items ### 📦 Container Layout container with responsive behavior. ```javascript const container = new Container({ fluid: false, safeArea: true, padding: 'default', // none, sm, default, lg, xl maxWidth: 'lg', // sm, md, lg, xl, full children: [ // Child elements ] }); ``` ## 🎨 Theming & Customization ### CSS Variables Customize the appearance using CSS variables: ```css :root { /* Colors */ --muspe-primary: #007AFF; --muspe-secondary: #FF9500; --muspe-success: #34C759; --muspe-warning: #FF9500; --muspe-error: #FF3B30; /* Spacing */ --muspe-space-1: 0.25rem; --muspe-space-2: 0.5rem; --muspe-space-3: 0.75rem; --muspe-space-4: 1rem; /* Typography */ --muspe-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; --muspe-font-size-base: 1rem; /* Border Radius */ --muspe-radius-sm: 0.375rem; --muspe-radius-md: 0.5rem; --muspe-radius-lg: 0.75rem; --muspe-radius-xl: 1rem; /* Shadows */ --muspe-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); --muspe-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); --muspe-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); } ``` ### Dark Mode Dark mode is automatically applied based on system preference: ```css @media (prefers-color-scheme: dark) { :root { --muspe-primary: #0A84FF; /* Other dark mode variables */ } } ``` Force dark mode: ```css [data-theme="dark"] { /* Dark mode styles */ } ``` ### Custom Variants Create custom button variants: ```css .muspe-button--custom { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; } .muspe-button--custom:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3); } ``` ## 📱 Mobile Optimizations ### Touch Interactions All components are optimized for touch: ```javascript // Automatic touch feedback button.element.addEventListener('touchstart', () => { button.element.classList.add('muspe-button--touching'); }); // Haptic feedback (where supported) if ('vibrate' in navigator) { navigator.vibrate(10); } ``` ### Safe Area Support Components automatically respect device safe areas: ```css .muspe-safe-area { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } ``` ### Responsive Breakpoints ```css /* Mobile First */ @media (min-width: 640px) { /* Small tablets */ } @media (min-width: 768px) { /* Tablets */ } @media (min-width: 1024px) { /* Laptops */ } @media (min-width: 1280px) { /* Desktops */ } ``` ## 🔧 Integration with MusPE Framework ### Reactive Components ```javascript import { reactive, computed } from '../core/reactivity.js'; const state = reactive({ count: 0, name: '' }); const button = new Button({ text: computed(() => `Count: ${state.count}`), callbacks: { onClick: () => state.count++ } }); ``` ### Component Integration ```javascript import { MusPEComponent } from '../core/component.js'; class MyComponent extends MusPEComponent { constructor(props) { super(props); this.button = new Button({ text: 'Click me', callbacks: { onClick: () => this.handleClick() } }); } render() { return h('div', {}, [ this.button.render() ]); } handleClick() { // Handle button click } } ``` ## 📖 Examples ### Complete Form ```javascript class ContactForm { constructor() { this.form = document.createElement('form'); this.setupInputs(); this.setupButton(); } setupInputs() { this.nameInput = new Input({ label: 'Name', required: true, callbacks: { onBlur: () => this.validateName() } }); this.emailInput = new Input({ type: 'email', label: 'Email', required: true, callbacks: { onBlur: () => this.validateEmail() } }); this.form.appendChild(this.nameInput.render()); this.form.appendChild(this.emailInput.render()); } setupButton() { this.submitButton = new Button({ text: 'Submit', variant: 'primary', fullWidth: true, callbacks: { onClick: () => this.submit() } }); this.form.appendChild(this.submitButton.render()); } validateName() { const value = this.nameInput.getValue().trim(); if (!value) { this.nameInput.setError('Name is required'); return false; } this.nameInput.setSuccess(); return true; } validateEmail() { const value = this.emailInput.getValue().trim(); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!value) { this.emailInput.setError('Email is required'); return false; } else if (!emailRegex.test(value)) { this.emailInput.setError('Please enter a valid email'); return false; } this.emailInput.setSuccess(); return true; } async submit() { if (!this.validateName() || !this.validateEmail()) { return; } this.submitButton.setLoading(true); try { // Submit form data const response = await fetch('/api/contact', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: this.nameInput.getValue(), email: this.emailInput.getValue() }) }); if (response.ok) { // Show success modal const modal = new Modal({ title: 'Success!', content: 'Your message has been sent.', size: 'sm', showFooter: true, footerActions: [ { text: 'OK', variant: 'primary' } ] }); modal.render(); modal.open(); } } catch (error) { console.error('Submit failed:', error); } finally { this.submitButton.setLoading(false); } } } ``` ### Mobile App Layout ```javascript class MobileApp { constructor() { this.setupNavbar(); this.setupContent(); this.setupToolbar(); } setupNavbar() { this.navbar = new Navbar({ title: 'My App', searchButton: true, callbacks: { onSearch: () => this.showSearch() } }); document.body.appendChild(this.navbar.render()); } setupContent() { this.container = new Container({ safeArea: true, padding: 'default' }); const content = document.createElement('div'); content.style.marginTop = '60px'; content.style.marginBottom = '60px'; content.style.minHeight = 'calc(100vh - 120px)'; this.container.setContent(content); document.body.appendChild(this.container.render()); } setupToolbar() { this.toolbar = new Toolbar({ items: [ { icon: '🏠', label: 'Home' }, { icon: '🔍', label: 'Search' }, { icon: '❤️', label: 'Favorites' }, { icon: '👤', label: 'Profile' } ], callbacks: { onItemClick: (index) => this.navigateToTab(index) } }); document.body.appendChild(this.toolbar.render()); } navigateToTab(index) { // Handle navigation console.log('Navigating to tab:', index); } showSearch() { // Show search interface console.log('Showing search'); } } // Initialize app const app = new MobileApp(); ``` ## 🚀 Performance Tips 1. **Lazy Loading**: Load components only when needed 2. **Event Delegation**: Use event delegation for better performance 3. **Virtual Scrolling**: For large lists, implement virtual scrolling 4. **Debouncing**: Debounce input events for better performance 5. **CSS Containment**: Use CSS containment for better rendering performance ## 📱 Browser Support - **iOS Safari**: 12+ - **Chrome Mobile**: 70+ - **Firefox Mobile**: 68+ - **Samsung Internet**: 10+ - **Desktop browsers**: Modern browsers with touch support ## 🤝 Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests 5. Submit a pull request ## 📄 License MIT License - see LICENSE file for details --- **MusPE UI Components** - Making mobile development beautiful and efficient! 📱✨