| @ -0,0 +1,285 @@ | |||
| # Concept Documentation Plan | |||
| ## Overview | |||
| Modern documentation for Concept - Bootstrap 5 Admin Dashboard Template with Vite build system. | |||
| ## Documentation Structure | |||
| ### 1. **README.md** (Main entry point) | |||
| - Project overview and key features | |||
| - Quick start guide | |||
| - Technology stack | |||
| - Browser support | |||
| - License information | |||
| - Links to detailed documentation | |||
| ### 2. **docs/** Directory Structure | |||
| ``` | |||
| docs/ | |||
| ├── getting-started/ | |||
| │ ├── introduction.md | |||
| │ ├── quick-start.md | |||
| │ ├── installation.md | |||
| │ ├── file-structure.md | |||
| │ └── build-tools.md | |||
| ├── customization/ | |||
| │ ├── overview.md | |||
| │ ├── theming.md | |||
| │ ├── sass-variables.md | |||
| │ ├── colors.md | |||
| │ └── components.md | |||
| ├── layout/ | |||
| │ ├── overview.md | |||
| │ ├── sidebar.md | |||
| │ ├── header.md | |||
| │ ├── footer.md | |||
| │ └── page-structure.md | |||
| ├── components/ | |||
| │ ├── alerts.md | |||
| │ ├── badges.md | |||
| │ ├── buttons.md | |||
| │ ├── cards.md | |||
| │ ├── forms.md | |||
| │ ├── modals.md | |||
| │ ├── tables.md | |||
| │ └── ... (all components) | |||
| ├── pages/ | |||
| │ ├── dashboards.md | |||
| │ ├── ecommerce.md | |||
| │ ├── email.md | |||
| │ ├── authentication.md | |||
| │ └── apps.md | |||
| ├── plugins/ | |||
| │ ├── charts.md | |||
| │ ├── datatables.md | |||
| │ ├── calendar.md | |||
| │ ├── editors.md | |||
| │ └── maps.md | |||
| ├── advanced/ | |||
| │ ├── javascript.md | |||
| │ ├── api-integration.md | |||
| │ ├── deployment.md | |||
| │ └── optimization.md | |||
| └── resources/ | |||
| ├── changelog.md | |||
| ├── credits.md | |||
| └── support.md | |||
| ``` | |||
| ## Content Details | |||
| ### 1. Getting Started Section | |||
| #### introduction.md | |||
| - What is Concept? | |||
| - Key features and benefits | |||
| - Template variants (dashboards, pages) | |||
| - What's included | |||
| - Community and support | |||
| #### quick-start.md | |||
| - Prerequisites (Node.js, npm) | |||
| - Download and extract | |||
| - Install dependencies | |||
| - Run development server | |||
| - Build for production | |||
| - Common issues and solutions | |||
| #### installation.md | |||
| - Detailed installation steps | |||
| - System requirements | |||
| - Package manager options (npm, yarn, pnpm) | |||
| - Environment setup | |||
| - Troubleshooting guide | |||
| #### file-structure.md | |||
| - Complete directory structure | |||
| - File naming conventions | |||
| - Important files explained | |||
| - Where to add custom code | |||
| - Build output structure | |||
| #### build-tools.md | |||
| - Vite configuration | |||
| - Development vs production builds | |||
| - Hot module replacement | |||
| - Asset optimization | |||
| - Custom build scripts | |||
| ### 2. Customization Section | |||
| #### theming.md | |||
| - Theme structure | |||
| - Creating custom themes | |||
| - Dark mode implementation | |||
| - RTL support | |||
| - Theme switching | |||
| #### sass-variables.md | |||
| - Variable organization | |||
| - Overriding Bootstrap variables | |||
| - Custom variables | |||
| - Responsive breakpoints | |||
| - Spacing system | |||
| #### colors.md | |||
| - Color palette | |||
| - Adding custom colors | |||
| - Color utilities | |||
| - Accessibility considerations | |||
| - Color schemes | |||
| ### 3. Layout Section | |||
| #### sidebar.md | |||
| - Sidebar structure | |||
| - Navigation configuration | |||
| - Menu items and badges | |||
| - Collapsible behavior | |||
| - Mobile responsiveness | |||
| #### header.md | |||
| - Header components | |||
| - Search functionality | |||
| - Notifications | |||
| - User menu | |||
| - Customization options | |||
| ### 4. Components Section | |||
| Each component documentation includes: | |||
| - Overview and usage | |||
| - Examples with code | |||
| - Props/options | |||
| - Methods/events | |||
| - Customization | |||
| - Accessibility notes | |||
| ### 5. Pages Section | |||
| Documentation for pre-built pages: | |||
| - How to use | |||
| - Customization points | |||
| - Data integration | |||
| - Common modifications | |||
| ### 6. Plugins Section | |||
| Third-party plugin documentation: | |||
| - Installation | |||
| - Configuration | |||
| - Usage examples | |||
| - API reference | |||
| - Common issues | |||
| ### 7. Advanced Section | |||
| #### javascript.md | |||
| - Module structure | |||
| - ES6 modules usage | |||
| - Event handling | |||
| - Data management | |||
| - Custom functions | |||
| #### deployment.md | |||
| - Production build | |||
| - Server requirements | |||
| - Deployment strategies | |||
| - Environment variables | |||
| - Performance optimization | |||
| ## Documentation Features | |||
| ### Code Examples | |||
| - Syntax highlighting | |||
| - Copy button | |||
| - Live previews where applicable | |||
| - Multiple language examples (HTML, JS, SCSS) | |||
| ### Navigation | |||
| - Search functionality | |||
| - Version selector | |||
| - Breadcrumbs | |||
| - Previous/Next links | |||
| - Table of contents | |||
| ### Interactive Elements | |||
| - Component playground | |||
| - Theme customizer | |||
| - Code sandbox integration | |||
| - API tester | |||
| ## Writing Guidelines | |||
| ### Style Guide | |||
| - Clear, concise language | |||
| - Present tense | |||
| - Active voice | |||
| - Step-by-step instructions | |||
| - Visual aids (screenshots, diagrams) | |||
| ### Code Standards | |||
| - Consistent formatting | |||
| - Comments for clarity | |||
| - Best practices highlighted | |||
| - Anti-patterns warned | |||
| ### SEO Optimization | |||
| - Descriptive titles | |||
| - Meta descriptions | |||
| - Proper heading hierarchy | |||
| - Alt text for images | |||
| - Semantic HTML | |||
| ## Implementation Steps | |||
| 1. **Phase 1: Core Documentation** | |||
| - README.md | |||
| - Getting started guide | |||
| - Basic customization | |||
| 2. **Phase 2: Component Documentation** | |||
| - All UI components | |||
| - Code examples | |||
| - Interactive demos | |||
| 3. **Phase 3: Advanced Topics** | |||
| - Plugin integration | |||
| - Deployment guides | |||
| - Performance optimization | |||
| 4. **Phase 4: Resources** | |||
| - Video tutorials | |||
| - FAQ section | |||
| - Troubleshooting guide | |||
| ## Tools and Technologies | |||
| ### Documentation Generator | |||
| - Consider using VitePress or similar | |||
| - Markdown-based | |||
| - Vue components for interactivity | |||
| - Search integration | |||
| ### Code Examples | |||
| - Prism.js for syntax highlighting | |||
| - CodePen/CodeSandbox embeds | |||
| - Copy-to-clipboard functionality | |||
| ### Versioning | |||
| - Git-based versioning | |||
| - Version switcher | |||
| - Migration guides | |||
| ## Maintenance Plan | |||
| ### Regular Updates | |||
| - New feature documentation | |||
| - Bug fix notes | |||
| - Security updates | |||
| - Community contributions | |||
| ### Feedback Integration | |||
| - User feedback forms | |||
| - GitHub issues tracking | |||
| - Documentation improvements | |||
| - FAQ updates | |||
| This plan ensures comprehensive, user-friendly documentation that helps developers quickly understand and effectively use the Concept template. | |||
| @ -0,0 +1,198 @@ | |||
| # Extended Documentation Plan for Concept | |||
| ## Already Completed ✅ | |||
| - Getting Started (introduction, quick-start, installation, file-structure, build-tools) | |||
| - Customization (overview, theming, sass-variables, colors) | |||
| ## Essential Documentation Still Needed | |||
| ### 1. **Components Documentation** 📦 | |||
| - `/docs/components/overview.md` - Component library overview | |||
| - `/docs/components/buttons.md` - Button variants, sizes, states | |||
| - `/docs/components/cards.md` - Card layouts and variations | |||
| - `/docs/components/forms.md` - Form controls, validation, layouts | |||
| - `/docs/components/tables.md` - Tables, DataTables integration | |||
| - `/docs/components/modals.md` - Modal dialogs and offcanvas | |||
| - `/docs/components/navigation.md` - Navbars, sidebars, breadcrumbs | |||
| - `/docs/components/alerts.md` - Alerts, toasts, notifications | |||
| - `/docs/components/charts.md` - Chart.js integration and examples | |||
| - `/docs/components/widgets.md` - Dashboard widgets and cards | |||
| ### 2. **Layout Documentation** 🎨 | |||
| - `/docs/layout/overview.md` - Layout system overview | |||
| - `/docs/layout/page-structure.md` - Page anatomy and templates | |||
| - `/docs/layout/sidebar.md` - Sidebar configuration and behavior | |||
| - `/docs/layout/header.md` - Header/navbar customization | |||
| - `/docs/layout/footer.md` - Footer options and content | |||
| - `/docs/layout/responsive.md` - Responsive design patterns | |||
| ### 3. **JavaScript/Functionality** ⚡ | |||
| - `/docs/javascript/overview.md` - JavaScript architecture | |||
| - `/docs/javascript/modules.md` - Module system and imports | |||
| - `/docs/javascript/initialization.md` - Component initialization | |||
| - `/docs/javascript/events.md` - Event handling patterns | |||
| - `/docs/javascript/api-integration.md` - API calls and data fetching | |||
| - `/docs/javascript/state-management.md` - Managing application state | |||
| ### 4. **Pages & Templates** 📄 | |||
| - `/docs/pages/overview.md` - Available page templates | |||
| - `/docs/pages/dashboards.md` - Dashboard variants | |||
| - `/docs/pages/auth-pages.md` - Authentication pages | |||
| - `/docs/pages/app-pages.md` - Application pages (calendar, chat, etc.) | |||
| - `/docs/pages/creating-pages.md` - How to create new pages | |||
| ### 5. **Advanced Topics** 🚀 | |||
| - `/docs/advanced/performance.md` - Performance optimization | |||
| - `/docs/advanced/security.md` - Security best practices | |||
| - `/docs/advanced/accessibility.md` - WCAG compliance | |||
| - `/docs/advanced/internationalization.md` - i18n/l10n support | |||
| - `/docs/advanced/testing.md` - Testing strategies | |||
| - `/docs/advanced/debugging.md` - Debugging techniques | |||
| - `/docs/advanced/browser-support.md` - Browser compatibility | |||
| ### 6. **Integration Guides** 🔌 | |||
| - `/docs/integration/backend.md` - Backend integration patterns | |||
| - `/docs/integration/authentication.md` - Auth system integration | |||
| - `/docs/integration/databases.md` - Database connections | |||
| - `/docs/integration/third-party.md` - Third-party services | |||
| - `/docs/integration/plugins.md` - Adding new plugins | |||
| - `/docs/integration/apis.md` - REST/GraphQL integration | |||
| ### 7. **Deployment** 🚢 | |||
| - `/docs/deployment/overview.md` - Deployment options | |||
| - `/docs/deployment/static-hosting.md` - Netlify, Vercel, etc. | |||
| - `/docs/deployment/server-deployment.md` - Node.js, nginx | |||
| - `/docs/deployment/docker.md` - Docker containerization | |||
| - `/docs/deployment/ci-cd.md` - CI/CD pipelines | |||
| - `/docs/deployment/monitoring.md` - Production monitoring | |||
| ### 8. **Migration & Upgrade** 🔄 | |||
| - `/docs/migration/from-v4.md` - Migrating from Bootstrap 4 version | |||
| - `/docs/migration/upgrade-guide.md` - Upgrading between versions | |||
| - `/docs/migration/breaking-changes.md` - Breaking changes log | |||
| - `/docs/migration/deprecations.md` - Deprecated features | |||
| ### 9. **Best Practices** 📚 | |||
| - `/docs/best-practices/code-style.md` - Coding standards | |||
| - `/docs/best-practices/project-structure.md` - Organizing code | |||
| - `/docs/best-practices/performance.md` - Performance tips | |||
| - `/docs/best-practices/seo.md` - SEO optimization | |||
| - `/docs/best-practices/security.md` - Security guidelines | |||
| ### 10. **Troubleshooting** 🔧 | |||
| - `/docs/troubleshooting/common-issues.md` - FAQ and solutions | |||
| - `/docs/troubleshooting/build-errors.md` - Build error solutions | |||
| - `/docs/troubleshooting/browser-issues.md` - Browser-specific fixes | |||
| - `/docs/troubleshooting/performance-issues.md` - Performance debugging | |||
| ### 11. **Reference** 📖 | |||
| - `/docs/reference/api.md` - JavaScript API reference | |||
| - `/docs/reference/sass-mixins.md` - Available Sass mixins | |||
| - `/docs/reference/css-classes.md` - CSS class reference | |||
| - `/docs/reference/icons.md` - Icon library reference | |||
| - `/docs/reference/utilities.md` - Utility classes | |||
| - `/docs/reference/changelog.md` - Version changelog | |||
| ### 12. **Examples & Tutorials** 💡 | |||
| - `/docs/examples/dashboard-tutorial.md` - Building a dashboard | |||
| - `/docs/examples/crud-application.md` - CRUD app example | |||
| - `/docs/examples/real-time-updates.md` - WebSocket integration | |||
| - `/docs/examples/data-visualization.md` - Advanced charts | |||
| - `/docs/examples/form-workflows.md` - Complex form patterns | |||
| ### 13. **Contributing** 🤝 | |||
| - `/docs/contributing/guidelines.md` - Contribution guidelines | |||
| - `/docs/contributing/development-setup.md` - Dev environment | |||
| - `/docs/contributing/pull-requests.md` - PR process | |||
| - `/docs/contributing/code-of-conduct.md` - Community standards | |||
| ### 14. **Resources** 🔗 | |||
| - `/docs/resources/learning.md` - Learning resources | |||
| - `/docs/resources/tools.md` - Recommended tools | |||
| - `/docs/resources/community.md` - Community links | |||
| - `/docs/resources/support.md` - Getting help | |||
| ## Documentation Features to Include | |||
| ### Interactive Elements | |||
| - Live code examples with CodePen/CodeSandbox | |||
| - Interactive component playground | |||
| - Search functionality | |||
| - Version switcher | |||
| - Dark mode for docs | |||
| ### Code Examples Should Include | |||
| - HTML markup | |||
| - JavaScript initialization | |||
| - SCSS customization | |||
| - Full working examples | |||
| - Common use cases | |||
| - Edge cases and gotchas | |||
| ### Each Component Doc Should Have | |||
| 1. Overview and use cases | |||
| 2. Basic examples | |||
| 3. Properties/options table | |||
| 4. Methods/API | |||
| 5. Events | |||
| 6. Accessibility notes | |||
| 7. Browser support | |||
| 8. Related components | |||
| ### Quality Standards | |||
| - Clear, concise writing | |||
| - Consistent formatting | |||
| - Proper code highlighting | |||
| - Screenshots where helpful | |||
| - Diagrams for complex concepts | |||
| - Performance considerations | |||
| - Mobile-specific notes | |||
| ## Priority Order for Implementation | |||
| ### Phase 1 (Critical) 🔴 | |||
| 1. Components documentation | |||
| 2. Layout documentation | |||
| 3. JavaScript/functionality basics | |||
| 4. Pages & templates overview | |||
| ### Phase 2 (Important) 🟡 | |||
| 5. Integration guides | |||
| 6. Deployment documentation | |||
| 7. Advanced topics | |||
| 8. Troubleshooting guide | |||
| ### Phase 3 (Nice to Have) 🟢 | |||
| 9. Migration guides | |||
| 10. Best practices | |||
| 11. Examples & tutorials | |||
| 12. Contributing guidelines | |||
| 13. Resources | |||
| ## Additional Considerations | |||
| ### Automated Documentation | |||
| - JSDoc for JavaScript API | |||
| - Sassdoc for SCSS documentation | |||
| - Component prop tables from code | |||
| - Auto-generated changelog | |||
| ### Versioning Strategy | |||
| - Separate docs for major versions | |||
| - Clear migration paths | |||
| - Deprecation warnings | |||
| - Version compatibility matrix | |||
| ### Search & Discovery | |||
| - Full-text search | |||
| - Tag-based filtering | |||
| - Related content suggestions | |||
| - Popular/trending sections | |||
| ### Feedback Mechanisms | |||
| - "Was this helpful?" buttons | |||
| - Comment system or GitHub discussions | |||
| - Edit on GitHub links | |||
| - Issue reporting integration | |||
| This comprehensive documentation will make Concept a professional, enterprise-ready template that developers can confidently use and customize for their projects. | |||
| @ -0,0 +1,262 @@ | |||
| # Buttons | |||
| Buttons are essential interactive elements. Concept extends Bootstrap's button styles with additional variants and states. | |||
| ## Basic Usage | |||
| ```html | |||
| <button type="button" class="btn btn-primary">Primary</button> | |||
| <button type="button" class="btn btn-secondary">Secondary</button> | |||
| <button type="button" class="btn btn-success">Success</button> | |||
| <button type="button" class="btn btn-danger">Danger</button> | |||
| <button type="button" class="btn btn-warning">Warning</button> | |||
| <button type="button" class="btn btn-info">Info</button> | |||
| <button type="button" class="btn btn-light">Light</button> | |||
| <button type="button" class="btn btn-dark">Dark</button> | |||
| ``` | |||
| ## Button Sizes | |||
| ```html | |||
| <button class="btn btn-primary btn-lg">Large button</button> | |||
| <button class="btn btn-primary">Default button</button> | |||
| <button class="btn btn-primary btn-sm">Small button</button> | |||
| ``` | |||
| ## Button Variants | |||
| ### Outline Buttons | |||
| ```html | |||
| <button class="btn btn-outline-primary">Primary</button> | |||
| <button class="btn btn-outline-secondary">Secondary</button> | |||
| <button class="btn btn-outline-success">Success</button> | |||
| ``` | |||
| ### Rounded Buttons | |||
| ```html | |||
| <button class="btn btn-primary rounded-pill">Pill Button</button> | |||
| <button class="btn btn-primary rounded-0">Square Button</button> | |||
| ``` | |||
| ### Icon Buttons | |||
| ```html | |||
| <!-- Icon only --> | |||
| <button class="btn btn-primary btn-icon"> | |||
| <i class="fa-solid fa-plus"></i> | |||
| </button> | |||
| <!-- Icon with text --> | |||
| <button class="btn btn-primary"> | |||
| <i class="fa-solid fa-download me-2"></i> | |||
| Download | |||
| </button> | |||
| ``` | |||
| ## Button States | |||
| ### Disabled State | |||
| ```html | |||
| <button class="btn btn-primary" disabled>Disabled button</button> | |||
| <a class="btn btn-primary disabled" role="button" aria-disabled="true">Disabled link</a> | |||
| ``` | |||
| ### Loading State | |||
| ```html | |||
| <button class="btn btn-primary" type="button" disabled> | |||
| <span class="spinner-border spinner-border-sm me-2" role="status"></span> | |||
| Loading... | |||
| </button> | |||
| ``` | |||
| ### Toggle State | |||
| ```html | |||
| <button type="button" class="btn btn-primary" data-bs-toggle="button"> | |||
| Toggle button | |||
| </button> | |||
| ``` | |||
| ## Button Groups | |||
| ### Basic Group | |||
| ```html | |||
| <div class="btn-group" role="group"> | |||
| <button type="button" class="btn btn-primary">Left</button> | |||
| <button type="button" class="btn btn-primary">Middle</button> | |||
| <button type="button" class="btn btn-primary">Right</button> | |||
| </div> | |||
| ``` | |||
| ### Vertical Group | |||
| ```html | |||
| <div class="btn-group-vertical" role="group"> | |||
| <button type="button" class="btn btn-primary">Top</button> | |||
| <button type="button" class="btn btn-primary">Middle</button> | |||
| <button type="button" class="btn btn-primary">Bottom</button> | |||
| </div> | |||
| ``` | |||
| ### Button Toolbar | |||
| ```html | |||
| <div class="btn-toolbar" role="toolbar"> | |||
| <div class="btn-group me-2" role="group"> | |||
| <button type="button" class="btn btn-primary">1</button> | |||
| <button type="button" class="btn btn-primary">2</button> | |||
| </div> | |||
| <div class="btn-group" role="group"> | |||
| <button type="button" class="btn btn-secondary">A</button> | |||
| <button type="button" class="btn btn-secondary">B</button> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Custom Button Styles | |||
| ### Gradient Buttons | |||
| ```scss | |||
| .btn-gradient-primary { | |||
| background: linear-gradient(135deg, $primary 0%, darken($primary, 10%) 100%); | |||
| border: none; | |||
| color: $white; | |||
| &:hover { | |||
| background: linear-gradient(135deg, darken($primary, 5%) 0%, darken($primary, 15%) 100%); | |||
| } | |||
| } | |||
| ``` | |||
| ### Social Media Buttons | |||
| ```html | |||
| <button class="btn btn-facebook"> | |||
| <i class="fa-brands fa-facebook-f me-2"></i> | |||
| </button> | |||
| <button class="btn btn-twitter"> | |||
| <i class="fa-brands fa-x-twitter me-2"></i> | |||
| </button> | |||
| ``` | |||
| ## JavaScript Usage | |||
| ### Dynamic Button Creation | |||
| ```javascript | |||
| // Create button element | |||
| const button = document.createElement('button'); | |||
| button.className = 'btn btn-primary'; | |||
| button.textContent = 'Dynamic Button'; | |||
| // Add click handler | |||
| button.addEventListener('click', () => { | |||
| console.log('Button clicked'); | |||
| }); | |||
| // Append to container | |||
| document.getElementById('button-container').appendChild(button); | |||
| ``` | |||
| ### Button State Management | |||
| ```javascript | |||
| // Loading state | |||
| function setLoading(button, loading = true) { | |||
| if (loading) { | |||
| button.disabled = true; | |||
| button.innerHTML = ` | |||
| <span class="spinner-border spinner-border-sm me-2"></span> | |||
| Loading... | |||
| `; | |||
| } else { | |||
| button.disabled = false; | |||
| button.textContent = 'Submit'; | |||
| } | |||
| } | |||
| // Toggle active state | |||
| document.querySelectorAll('[data-toggle-group] .btn').forEach(btn => { | |||
| btn.addEventListener('click', function() { | |||
| // Remove active from siblings | |||
| this.parentElement.querySelectorAll('.btn').forEach(b => { | |||
| b.classList.remove('active'); | |||
| }); | |||
| // Add active to clicked | |||
| this.classList.add('active'); | |||
| }); | |||
| }); | |||
| ``` | |||
| ## Accessibility | |||
| ### ARIA Labels | |||
| ```html | |||
| <!-- Icon-only button --> | |||
| <button class="btn btn-primary" aria-label="Add new item"> | |||
| <i class="fa-solid fa-plus"></i> | |||
| </button> | |||
| <!-- Loading button --> | |||
| <button class="btn btn-primary" disabled> | |||
| <span class="spinner-border spinner-border-sm" role="status"> | |||
| <span class="visually-hidden">Loading...</span> | |||
| </span> | |||
| </button> | |||
| ``` | |||
| ### Keyboard Navigation | |||
| - All buttons must be keyboard accessible | |||
| - Use `tabindex="0"` for custom button elements | |||
| - Provide visual focus indicators | |||
| - Support Enter and Space key activation | |||
| ## Best Practices | |||
| ### DO: | |||
| - Use semantic button elements when possible | |||
| - Provide clear button labels | |||
| - Include hover and focus states | |||
| - Test keyboard navigation | |||
| - Use appropriate button sizes for touch | |||
| ### DON'T: | |||
| - Don't use buttons for navigation (use links) | |||
| - Don't disable buttons without explanation | |||
| - Don't remove focus indicators | |||
| - Don't make touch targets too small | |||
| ## Common Patterns | |||
| ### Confirmation Buttons | |||
| ```html | |||
| <button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#confirmModal"> | |||
| Delete | |||
| </button> | |||
| <!-- Confirmation Modal --> | |||
| <div class="modal fade" id="confirmModal"> | |||
| <div class="modal-dialog"> | |||
| <div class="modal-content"> | |||
| <div class="modal-body"> | |||
| Are you sure you want to delete this item? | |||
| </div> | |||
| <div class="modal-footer"> | |||
| <button class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> | |||
| <button class="btn btn-danger">Delete</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Button with Dropdown | |||
| ```html | |||
| <div class="btn-group"> | |||
| <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown"> | |||
| Actions | |||
| </button> | |||
| <ul class="dropdown-menu"> | |||
| <li><a class="dropdown-item" href="#">Edit</a></li> | |||
| <li><a class="dropdown-item" href="#">Duplicate</a></li> | |||
| <li><hr class="dropdown-divider"></li> | |||
| <li><a class="dropdown-item text-danger" href="#">Delete</a></li> | |||
| </ul> | |||
| </div> | |||
| ``` | |||
| @ -0,0 +1,348 @@ | |||
| # Cards | |||
| Cards are flexible content containers with multiple variants for displaying different types of content. | |||
| ## Basic Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card Title</h5> | |||
| <p class="card-text">Some quick example text to build on the card title.</p> | |||
| <a href="#" class="btn btn-primary">Go somewhere</a> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Card Components | |||
| ### Card Header & Footer | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-header"> | |||
| Featured | |||
| </div> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Special title treatment</h5> | |||
| <p class="card-text">With supporting text below.</p> | |||
| </div> | |||
| <div class="card-footer text-muted"> | |||
| 2 days ago | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Card with Image | |||
| ```html | |||
| <div class="card"> | |||
| <img src="..." class="card-img-top" alt="..."> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card title</h5> | |||
| <p class="card-text">Card content</p> | |||
| </div> | |||
| </div> | |||
| <!-- Image overlay --> | |||
| <div class="card text-white"> | |||
| <img src="..." class="card-img" alt="..."> | |||
| <div class="card-img-overlay"> | |||
| <h5 class="card-title">Card title</h5> | |||
| <p class="card-text">Overlay content</p> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Card Variations | |||
| ### Bordered Cards | |||
| ```html | |||
| <div class="card border-primary"> | |||
| <div class="card-header">Header</div> | |||
| <div class="card-body text-primary"> | |||
| <h5 class="card-title">Primary card</h5> | |||
| <p class="card-text">Example text content.</p> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Background Colors | |||
| ```html | |||
| <div class="card text-white bg-primary"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Primary card</h5> | |||
| <p class="card-text">White text on colored background.</p> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Card without Border | |||
| ```html | |||
| <div class="card border-0 shadow"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Borderless Card</h5> | |||
| <p class="card-text">Card with shadow instead of border.</p> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Dashboard Cards | |||
| ### Stat Card | |||
| ```html | |||
| <div class="card border-0"> | |||
| <div class="card-body"> | |||
| <div class="d-flex justify-content-between align-items-center"> | |||
| <div> | |||
| <h6 class="text-muted mb-2">Total Revenue</h6> | |||
| <h3 class="mb-0">$24,563</h3> | |||
| <small class="text-success"> | |||
| <i class="fa-solid fa-arrow-up"></i> 12.5% | |||
| </small> | |||
| </div> | |||
| <div class="icon-shape icon-md bg-primary-soft text-primary rounded-circle"> | |||
| <i class="fa-solid fa-dollar-sign"></i> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Chart Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-header d-flex justify-content-between align-items-center"> | |||
| <h5 class="card-title mb-0">Sales Overview</h5> | |||
| <div class="dropdown"> | |||
| <button class="btn btn-sm btn-light" data-bs-toggle="dropdown"> | |||
| <i class="fa-solid fa-ellipsis-v"></i> | |||
| </button> | |||
| <ul class="dropdown-menu"> | |||
| <li><a class="dropdown-item" href="#">Daily</a></li> | |||
| <li><a class="dropdown-item" href="#">Weekly</a></li> | |||
| <li><a class="dropdown-item" href="#">Monthly</a></li> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| <div class="card-body"> | |||
| <canvas id="salesChart"></canvas> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Activity Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-header"> | |||
| <h5 class="card-title mb-0">Recent Activity</h5> | |||
| </div> | |||
| <div class="card-body"> | |||
| <ul class="list-unstyled mb-0"> | |||
| <li class="d-flex align-items-center mb-3"> | |||
| <div class="avatar avatar-sm me-3"> | |||
| <img src="..." class="rounded-circle" alt="User"> | |||
| </div> | |||
| <div class="flex-grow-1"> | |||
| <h6 class="mb-0">John Doe</h6> | |||
| <small class="text-muted">Completed task - 2 hours ago</small> | |||
| </div> | |||
| </li> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Card Layouts | |||
| ### Card Group | |||
| ```html | |||
| <div class="card-group"> | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card 1</h5> | |||
| </div> | |||
| </div> | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card 2</h5> | |||
| </div> | |||
| </div> | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card 3</h5> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Card Grid | |||
| ```html | |||
| <div class="row g-4"> | |||
| <div class="col-md-6 col-lg-4"> | |||
| <div class="card h-100"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card 1</h5> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="col-md-6 col-lg-4"> | |||
| <div class="card h-100"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Card 2</h5> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Interactive Cards | |||
| ### Clickable Card | |||
| ```html | |||
| <div class="card card-hover" onclick="window.location='#'"> | |||
| <div class="card-body"> | |||
| <h5 class="card-title">Clickable Card</h5> | |||
| <p class="card-text">Entire card is clickable.</p> | |||
| </div> | |||
| </div> | |||
| <style> | |||
| .card-hover { | |||
| cursor: pointer; | |||
| transition: transform 0.2s, box-shadow 0.2s; | |||
| } | |||
| .card-hover:hover { | |||
| transform: translateY(-4px); | |||
| box-shadow: 0 4px 12px rgba(0,0,0,0.15); | |||
| } | |||
| </style> | |||
| ``` | |||
| ### Collapsible Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-header" data-bs-toggle="collapse" data-bs-target="#collapseCard"> | |||
| <h5 class="card-title mb-0"> | |||
| Collapsible Card | |||
| <i class="fa-solid fa-chevron-down float-end"></i> | |||
| </h5> | |||
| </div> | |||
| <div id="collapseCard" class="collapse show"> | |||
| <div class="card-body"> | |||
| Card content that can be toggled. | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Custom Card Styles | |||
| ### Loading Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| <div class="text-center py-5"> | |||
| <div class="spinner-border text-primary" role="status"> | |||
| <span class="visually-hidden">Loading...</span> | |||
| </div> | |||
| <p class="mt-3 mb-0">Loading content...</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Empty State Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-body text-center py-5"> | |||
| <i class="fa-solid fa-inbox fa-3x text-muted mb-3"></i> | |||
| <h5>No Data Available</h5> | |||
| <p class="text-muted">There's nothing to display at the moment.</p> | |||
| <button class="btn btn-primary">Add New Item</button> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## JavaScript Usage | |||
| ### Dynamic Card Creation | |||
| ```javascript | |||
| function createStatCard(title, value, change, icon) { | |||
| return ` | |||
| <div class="card border-0"> | |||
| <div class="card-body"> | |||
| <div class="d-flex justify-content-between align-items-center"> | |||
| <div> | |||
| <h6 class="text-muted mb-2">${title}</h6> | |||
| <h3 class="mb-0">${value}</h3> | |||
| <small class="${change >= 0 ? 'text-success' : 'text-danger'}"> | |||
| <i class="fa-solid fa-arrow-${change >= 0 ? 'up' : 'down'}"></i> | |||
| ${Math.abs(change)}% | |||
| </small> | |||
| </div> | |||
| <div class="icon-shape icon-md bg-primary-soft text-primary rounded-circle"> | |||
| <i class="${icon}"></i> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| `; | |||
| } | |||
| // Usage | |||
| const container = document.getElementById('stats-container'); | |||
| container.innerHTML = createStatCard('Revenue', '$12,345', 5.2, 'fa-solid fa-dollar-sign'); | |||
| ``` | |||
| ### Card State Management | |||
| ```javascript | |||
| // Toggle card loading state | |||
| function setCardLoading(card, loading = true) { | |||
| const cardBody = card.querySelector('.card-body'); | |||
| if (loading) { | |||
| cardBody.innerHTML = ` | |||
| <div class="text-center py-5"> | |||
| <div class="spinner-border text-primary" role="status"></div> | |||
| </div> | |||
| `; | |||
| } else { | |||
| // Restore content | |||
| } | |||
| } | |||
| // Refresh card content | |||
| async function refreshCard(cardId) { | |||
| const card = document.getElementById(cardId); | |||
| setCardLoading(card, true); | |||
| try { | |||
| const data = await fetchCardData(cardId); | |||
| updateCardContent(card, data); | |||
| } finally { | |||
| setCardLoading(card, false); | |||
| } | |||
| } | |||
| ``` | |||
| ## Accessibility | |||
| - Use semantic HTML structure | |||
| - Provide appropriate headings hierarchy | |||
| - Include alt text for images | |||
| - Ensure sufficient color contrast | |||
| - Make interactive cards keyboard accessible | |||
| ## Best Practices | |||
| ### DO: | |||
| - Keep card content concise | |||
| - Use consistent spacing | |||
| - Group related information | |||
| - Provide visual hierarchy | |||
| - Test responsive behavior | |||
| ### DON'T: | |||
| - Don't overload cards with content | |||
| - Don't mix too many card styles | |||
| - Don't forget hover/focus states | |||
| - Don't use cards for everything | |||
| @ -0,0 +1,557 @@ | |||
| # Charts | |||
| Concept uses Chart.js for creating responsive, animated charts. This guide covers implementation and customization. | |||
| ## Setup | |||
| ### Basic Initialization | |||
| ```javascript | |||
| import Chart from 'chart.js/auto'; | |||
| // Get canvas element | |||
| const ctx = document.getElementById('myChart').getContext('2d'); | |||
| // Create chart | |||
| const myChart = new Chart(ctx, { | |||
| type: 'line', | |||
| data: { | |||
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], | |||
| datasets: [{ | |||
| label: 'Sales', | |||
| data: [12, 19, 3, 5, 2, 3], | |||
| borderColor: '#5969ff', | |||
| backgroundColor: 'rgba(89, 105, 255, 0.1)' | |||
| }] | |||
| } | |||
| }); | |||
| ``` | |||
| ## Chart Types | |||
| ### Line Chart | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'line', | |||
| data: { | |||
| labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | |||
| datasets: [{ | |||
| label: 'This Week', | |||
| data: [65, 59, 80, 81, 56, 55, 40], | |||
| borderColor: '#5969ff', | |||
| backgroundColor: 'rgba(89, 105, 255, 0.1)', | |||
| tension: 0.4 | |||
| }, { | |||
| label: 'Last Week', | |||
| data: [45, 39, 60, 71, 46, 35, 30], | |||
| borderColor: '#ff407b', | |||
| backgroundColor: 'rgba(255, 64, 123, 0.1)', | |||
| tension: 0.4 | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| plugins: { | |||
| legend: { | |||
| position: 'top', | |||
| } | |||
| }, | |||
| scales: { | |||
| y: { | |||
| beginAtZero: true | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ### Bar Chart | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'bar', | |||
| data: { | |||
| labels: ['Q1', 'Q2', 'Q3', 'Q4'], | |||
| datasets: [{ | |||
| label: '2023', | |||
| data: [12000, 19000, 15000, 25000], | |||
| backgroundColor: '#5969ff' | |||
| }, { | |||
| label: '2024', | |||
| data: [15000, 23000, 18000, 29000], | |||
| backgroundColor: '#ff407b' | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| plugins: { | |||
| legend: { | |||
| position: 'top', | |||
| } | |||
| }, | |||
| scales: { | |||
| y: { | |||
| beginAtZero: true, | |||
| ticks: { | |||
| callback: function(value) { | |||
| return '$' + value.toLocaleString(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ### Pie/Doughnut Chart | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'doughnut', | |||
| data: { | |||
| labels: ['Desktop', 'Mobile', 'Tablet'], | |||
| datasets: [{ | |||
| data: [55, 30, 15], | |||
| backgroundColor: [ | |||
| '#5969ff', | |||
| '#ff407b', | |||
| '#25d5f2' | |||
| ], | |||
| borderWidth: 0 | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| plugins: { | |||
| legend: { | |||
| position: 'bottom' | |||
| }, | |||
| tooltip: { | |||
| callbacks: { | |||
| label: function(context) { | |||
| return context.label + ': ' + context.parsed + '%'; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ### Area Chart | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'line', | |||
| data: { | |||
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], | |||
| datasets: [{ | |||
| label: 'Revenue', | |||
| data: [10, 25, 20, 30, 45, 40], | |||
| borderColor: '#5969ff', | |||
| backgroundColor: 'rgba(89, 105, 255, 0.2)', | |||
| fill: true, | |||
| tension: 0.4 | |||
| }] | |||
| } | |||
| }); | |||
| ``` | |||
| ## Dashboard Charts | |||
| ### Revenue Chart | |||
| ```javascript | |||
| function createRevenueChart(canvasId) { | |||
| const ctx = document.getElementById(canvasId).getContext('2d'); | |||
| return new Chart(ctx, { | |||
| type: 'line', | |||
| data: { | |||
| labels: getLast12Months(), | |||
| datasets: [{ | |||
| label: 'Revenue', | |||
| data: [45000, 52000, 48000, 58000, 63000, 72000, | |||
| 78000, 82000, 79000, 85000, 91000, 95000], | |||
| borderColor: '#5969ff', | |||
| backgroundColor: 'rgba(89, 105, 255, 0.05)', | |||
| borderWidth: 3, | |||
| fill: true, | |||
| tension: 0.4, | |||
| pointRadius: 0, | |||
| pointHoverRadius: 6 | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| maintainAspectRatio: false, | |||
| plugins: { | |||
| legend: { | |||
| display: false | |||
| }, | |||
| tooltip: { | |||
| backgroundColor: 'rgba(0, 0, 0, 0.8)', | |||
| titleColor: '#fff', | |||
| bodyColor: '#fff', | |||
| borderColor: '#ddd', | |||
| borderWidth: 1, | |||
| padding: 10, | |||
| displayColors: false, | |||
| callbacks: { | |||
| label: function(context) { | |||
| return 'Revenue: $' + context.parsed.y.toLocaleString(); | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| scales: { | |||
| x: { | |||
| grid: { | |||
| display: false | |||
| } | |||
| }, | |||
| y: { | |||
| beginAtZero: false, | |||
| ticks: { | |||
| callback: function(value) { | |||
| return '$' + (value / 1000) + 'k'; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| ``` | |||
| ### Real-time Chart | |||
| ```javascript | |||
| class RealtimeChart { | |||
| constructor(canvasId) { | |||
| this.chart = new Chart(document.getElementById(canvasId), { | |||
| type: 'line', | |||
| data: { | |||
| labels: [], | |||
| datasets: [{ | |||
| label: 'Active Users', | |||
| data: [], | |||
| borderColor: '#5969ff', | |||
| backgroundColor: 'rgba(89, 105, 255, 0.1)', | |||
| borderWidth: 2, | |||
| fill: true | |||
| }] | |||
| }, | |||
| options: { | |||
| responsive: true, | |||
| scales: { | |||
| x: { | |||
| type: 'realtime', | |||
| realtime: { | |||
| duration: 20000, | |||
| refresh: 1000, | |||
| delay: 2000, | |||
| onRefresh: chart => { | |||
| chart.data.datasets.forEach(dataset => { | |||
| dataset.data.push({ | |||
| x: Date.now(), | |||
| y: Math.random() * 100 | |||
| }); | |||
| }); | |||
| } | |||
| } | |||
| }, | |||
| y: { | |||
| beginAtZero: true | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| start() { | |||
| this.chart.options.scales.x.realtime.pause = false; | |||
| this.chart.update('none'); | |||
| } | |||
| stop() { | |||
| this.chart.options.scales.x.realtime.pause = true; | |||
| this.chart.update('none'); | |||
| } | |||
| } | |||
| ``` | |||
| ## Advanced Features | |||
| ### Mixed Chart Types | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'bar', | |||
| data: { | |||
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], | |||
| datasets: [{ | |||
| type: 'bar', | |||
| label: 'Sales', | |||
| data: [12, 19, 3, 5, 2, 3], | |||
| backgroundColor: '#5969ff' | |||
| }, { | |||
| type: 'line', | |||
| label: 'Profit', | |||
| data: [5, 8, 2, 3, 1, 2], | |||
| borderColor: '#ff407b', | |||
| backgroundColor: 'transparent', | |||
| yAxisID: 'y1' | |||
| }] | |||
| }, | |||
| options: { | |||
| scales: { | |||
| y: { | |||
| beginAtZero: true, | |||
| position: 'left' | |||
| }, | |||
| y1: { | |||
| beginAtZero: true, | |||
| position: 'right', | |||
| grid: { | |||
| drawOnChartArea: false | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ### Dynamic Updates | |||
| ```javascript | |||
| // Update chart data | |||
| function updateChartData(chart, newData) { | |||
| chart.data.datasets[0].data = newData; | |||
| chart.update(); | |||
| } | |||
| // Add data point | |||
| function addDataPoint(chart, label, value) { | |||
| chart.data.labels.push(label); | |||
| chart.data.datasets.forEach((dataset) => { | |||
| dataset.data.push(value); | |||
| }); | |||
| chart.update(); | |||
| } | |||
| // Remove data point | |||
| function removeDataPoint(chart) { | |||
| chart.data.labels.shift(); | |||
| chart.data.datasets.forEach((dataset) => { | |||
| dataset.data.shift(); | |||
| }); | |||
| chart.update(); | |||
| } | |||
| ``` | |||
| ### Chart Interactions | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'bar', | |||
| data: chartData, | |||
| options: { | |||
| onClick: (event, activeElements) => { | |||
| if (activeElements.length > 0) { | |||
| const dataIndex = activeElements[0].index; | |||
| const label = chart.data.labels[dataIndex]; | |||
| console.log('Clicked on:', label); | |||
| // Handle click | |||
| } | |||
| }, | |||
| onHover: (event, activeElements) => { | |||
| ctx.canvas.style.cursor = activeElements.length > 0 ? 'pointer' : 'default'; | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ## Responsive Charts | |||
| ### Container-based Sizing | |||
| ```html | |||
| <div class="chart-container" style="position: relative; height:400px;"> | |||
| <canvas id="responsiveChart"></canvas> | |||
| </div> | |||
| ``` | |||
| ```javascript | |||
| new Chart(document.getElementById('responsiveChart'), { | |||
| type: 'line', | |||
| data: data, | |||
| options: { | |||
| responsive: true, | |||
| maintainAspectRatio: false | |||
| } | |||
| }); | |||
| ``` | |||
| ### Responsive Options | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'bar', | |||
| data: data, | |||
| options: { | |||
| responsive: true, | |||
| aspectRatio: 2, | |||
| resizeDelay: 200, | |||
| plugins: { | |||
| legend: { | |||
| display: window.innerWidth > 768, | |||
| position: window.innerWidth > 768 ? 'right' : 'top' | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ## Custom Styling | |||
| ### Theme Colors | |||
| ```javascript | |||
| // Define theme colors | |||
| const chartColors = { | |||
| primary: '#5969ff', | |||
| secondary: '#6c757d', | |||
| success: '#28a745', | |||
| danger: '#dc3545', | |||
| warning: '#ffc107', | |||
| info: '#17a2b8' | |||
| }; | |||
| // Use in charts | |||
| new Chart(ctx, { | |||
| type: 'bar', | |||
| data: { | |||
| datasets: [{ | |||
| backgroundColor: [ | |||
| chartColors.primary, | |||
| chartColors.success, | |||
| chartColors.warning, | |||
| chartColors.danger | |||
| ] | |||
| }] | |||
| } | |||
| }); | |||
| ``` | |||
| ### Gradient Fills | |||
| ```javascript | |||
| // Create gradient | |||
| const gradient = ctx.createLinearGradient(0, 0, 0, 400); | |||
| gradient.addColorStop(0, 'rgba(89, 105, 255, 0.5)'); | |||
| gradient.addColorStop(1, 'rgba(89, 105, 255, 0)'); | |||
| new Chart(ctx, { | |||
| type: 'line', | |||
| data: { | |||
| datasets: [{ | |||
| backgroundColor: gradient, | |||
| fill: true | |||
| }] | |||
| } | |||
| }); | |||
| ``` | |||
| ## Chart Utilities | |||
| ### Export Chart | |||
| ```javascript | |||
| function exportChart(chart, filename = 'chart.png') { | |||
| const link = document.createElement('a'); | |||
| link.download = filename; | |||
| link.href = chart.toBase64Image(); | |||
| link.click(); | |||
| } | |||
| // Usage | |||
| const exportBtn = document.getElementById('exportBtn'); | |||
| exportBtn.addEventListener('click', () => { | |||
| exportChart(myChart, 'sales-report.png'); | |||
| }); | |||
| ``` | |||
| ### Chart Loading State | |||
| ```javascript | |||
| function showChartLoading(canvasId) { | |||
| const canvas = document.getElementById(canvasId); | |||
| const parent = canvas.parentElement; | |||
| parent.innerHTML = ` | |||
| <div class="d-flex justify-content-center align-items-center" style="height: 400px;"> | |||
| <div class="spinner-border text-primary" role="status"> | |||
| <span class="visually-hidden">Loading...</span> | |||
| </div> | |||
| </div> | |||
| `; | |||
| } | |||
| async function loadChartData(url, canvasId) { | |||
| showChartLoading(canvasId); | |||
| try { | |||
| const response = await fetch(url); | |||
| const data = await response.json(); | |||
| // Recreate canvas | |||
| const parent = document.querySelector(`#${canvasId}`).parentElement; | |||
| parent.innerHTML = `<canvas id="${canvasId}"></canvas>`; | |||
| // Create chart | |||
| new Chart(document.getElementById(canvasId), data); | |||
| } catch (error) { | |||
| console.error('Failed to load chart data:', error); | |||
| } | |||
| } | |||
| ``` | |||
| ## Performance Tips | |||
| ### Data Decimation | |||
| ```javascript | |||
| new Chart(ctx, { | |||
| type: 'line', | |||
| data: largeDataset, | |||
| options: { | |||
| parsing: false, | |||
| normalized: true, | |||
| animation: false, | |||
| plugins: { | |||
| decimation: { | |||
| enabled: true, | |||
| algorithm: 'lttb', | |||
| samples: 500 | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ### Disable Animations | |||
| ```javascript | |||
| // Globally | |||
| Chart.defaults.animation = false; | |||
| // Per chart | |||
| new Chart(ctx, { | |||
| options: { | |||
| animation: { | |||
| duration: 0 | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ## Best Practices | |||
| ### DO: | |||
| - Choose appropriate chart types for data | |||
| - Keep charts simple and focused | |||
| - Use consistent color schemes | |||
| - Provide context with labels and legends | |||
| - Make charts responsive | |||
| - Test on different screen sizes | |||
| ### DON'T: | |||
| - Don't overload charts with data | |||
| - Don't use 3D effects unnecessarily | |||
| - Don't forget accessibility | |||
| - Don't use too many colors | |||
| - Don't ignore mobile users | |||
| @ -0,0 +1,459 @@ | |||
| # Forms | |||
| Comprehensive form components and patterns for building user-friendly forms with validation. | |||
| ## Basic Form Elements | |||
| ### Text Inputs | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="basicInput" class="form-label">Basic Input</label> | |||
| <input type="text" class="form-control" id="basicInput" placeholder="Enter text"> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="emailInput" class="form-label">Email</label> | |||
| <input type="email" class="form-control" id="emailInput" placeholder="name@example.com"> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="passwordInput" class="form-label">Password</label> | |||
| <input type="password" class="form-control" id="passwordInput"> | |||
| </div> | |||
| ``` | |||
| ### Textarea | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="textarea" class="form-label">Message</label> | |||
| <textarea class="form-control" id="textarea" rows="3"></textarea> | |||
| </div> | |||
| ``` | |||
| ### Select | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="selectInput" class="form-label">Select Option</label> | |||
| <select class="form-select" id="selectInput"> | |||
| <option selected>Choose...</option> | |||
| <option value="1">Option 1</option> | |||
| <option value="2">Option 2</option> | |||
| <option value="3">Option 3</option> | |||
| </select> | |||
| </div> | |||
| <!-- Multiple select --> | |||
| <select class="form-select" multiple> | |||
| <option value="1">Option 1</option> | |||
| <option value="2">Option 2</option> | |||
| <option value="3">Option 3</option> | |||
| </select> | |||
| ``` | |||
| ### Checkboxes and Radios | |||
| ```html | |||
| <!-- Checkbox --> | |||
| <div class="form-check"> | |||
| <input class="form-check-input" type="checkbox" id="checkbox1"> | |||
| <label class="form-check-label" for="checkbox1"> | |||
| Default checkbox | |||
| </label> | |||
| </div> | |||
| <!-- Radio --> | |||
| <div class="form-check"> | |||
| <input class="form-check-input" type="radio" name="radioOptions" id="radio1" checked> | |||
| <label class="form-check-label" for="radio1"> | |||
| Default radio | |||
| </label> | |||
| </div> | |||
| <!-- Switch --> | |||
| <div class="form-check form-switch"> | |||
| <input class="form-check-input" type="checkbox" id="switch1"> | |||
| <label class="form-check-label" for="switch1"> | |||
| Toggle switch | |||
| </label> | |||
| </div> | |||
| ``` | |||
| ## Form Layouts | |||
| ### Vertical Form | |||
| ```html | |||
| <form> | |||
| <div class="mb-3"> | |||
| <label for="name" class="form-label">Name</label> | |||
| <input type="text" class="form-control" id="name"> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="email" class="form-label">Email</label> | |||
| <input type="email" class="form-control" id="email"> | |||
| </div> | |||
| <button type="submit" class="btn btn-primary">Submit</button> | |||
| </form> | |||
| ``` | |||
| ### Horizontal Form | |||
| ```html | |||
| <form> | |||
| <div class="row mb-3"> | |||
| <label for="inputEmail" class="col-sm-2 col-form-label">Email</label> | |||
| <div class="col-sm-10"> | |||
| <input type="email" class="form-control" id="inputEmail"> | |||
| </div> | |||
| </div> | |||
| <div class="row mb-3"> | |||
| <label for="inputPassword" class="col-sm-2 col-form-label">Password</label> | |||
| <div class="col-sm-10"> | |||
| <input type="password" class="form-control" id="inputPassword"> | |||
| </div> | |||
| </div> | |||
| <button type="submit" class="btn btn-primary">Sign in</button> | |||
| </form> | |||
| ``` | |||
| ### Inline Form | |||
| ```html | |||
| <form class="row row-cols-lg-auto g-3 align-items-center"> | |||
| <div class="col-12"> | |||
| <input type="text" class="form-control" placeholder="Username"> | |||
| </div> | |||
| <div class="col-12"> | |||
| <input type="password" class="form-control" placeholder="Password"> | |||
| </div> | |||
| <div class="col-12"> | |||
| <button type="submit" class="btn btn-primary">Login</button> | |||
| </div> | |||
| </form> | |||
| ``` | |||
| ## Input Groups | |||
| ### Basic Input Group | |||
| ```html | |||
| <div class="input-group mb-3"> | |||
| <span class="input-group-text">@</span> | |||
| <input type="text" class="form-control" placeholder="Username"> | |||
| </div> | |||
| <div class="input-group mb-3"> | |||
| <input type="text" class="form-control" placeholder="Price"> | |||
| <span class="input-group-text">.00</span> | |||
| </div> | |||
| <div class="input-group mb-3"> | |||
| <span class="input-group-text">$</span> | |||
| <input type="text" class="form-control"> | |||
| <span class="input-group-text">.00</span> | |||
| </div> | |||
| ``` | |||
| ### With Buttons | |||
| ```html | |||
| <div class="input-group mb-3"> | |||
| <input type="text" class="form-control" placeholder="Search..."> | |||
| <button class="btn btn-primary" type="button"> | |||
| <i class="fa-solid fa-search"></i> | |||
| </button> | |||
| </div> | |||
| ``` | |||
| ## Form Validation | |||
| ### HTML5 Validation | |||
| ```html | |||
| <form class="needs-validation" novalidate> | |||
| <div class="mb-3"> | |||
| <label for="validationCustom01" class="form-label">First name</label> | |||
| <input type="text" class="form-control" id="validationCustom01" required> | |||
| <div class="valid-feedback"> | |||
| Looks good! | |||
| </div> | |||
| <div class="invalid-feedback"> | |||
| Please provide a valid first name. | |||
| </div> | |||
| </div> | |||
| <button class="btn btn-primary" type="submit">Submit</button> | |||
| </form> | |||
| <script> | |||
| // Bootstrap validation | |||
| (function() { | |||
| 'use strict'; | |||
| const forms = document.querySelectorAll('.needs-validation'); | |||
| Array.from(forms).forEach(form => { | |||
| form.addEventListener('submit', event => { | |||
| if (!form.checkValidity()) { | |||
| event.preventDefault(); | |||
| event.stopPropagation(); | |||
| } | |||
| form.classList.add('was-validated'); | |||
| }, false); | |||
| }); | |||
| })(); | |||
| </script> | |||
| ``` | |||
| ### Custom Validation | |||
| ```javascript | |||
| // Real-time validation | |||
| function validateEmail(input) { | |||
| const email = input.value; | |||
| const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); | |||
| if (isValid) { | |||
| input.classList.remove('is-invalid'); | |||
| input.classList.add('is-valid'); | |||
| } else { | |||
| input.classList.remove('is-valid'); | |||
| input.classList.add('is-invalid'); | |||
| } | |||
| } | |||
| // Password strength checker | |||
| function checkPasswordStrength(password) { | |||
| let strength = 0; | |||
| if (password.length >= 8) strength++; | |||
| if (/[a-z]/.test(password)) strength++; | |||
| if (/[A-Z]/.test(password)) strength++; | |||
| if (/[0-9]/.test(password)) strength++; | |||
| if (/[^A-Za-z0-9]/.test(password)) strength++; | |||
| return { | |||
| score: strength, | |||
| label: ['Very Weak', 'Weak', 'Fair', 'Good', 'Strong'][strength] | |||
| }; | |||
| } | |||
| ``` | |||
| ## Advanced Form Components | |||
| ### File Upload | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="formFile" class="form-label">Default file input</label> | |||
| <input class="form-control" type="file" id="formFile"> | |||
| </div> | |||
| <!-- Multiple files --> | |||
| <div class="mb-3"> | |||
| <label for="formFileMultiple" class="form-label">Multiple files</label> | |||
| <input class="form-control" type="file" id="formFileMultiple" multiple> | |||
| </div> | |||
| <!-- Custom file upload --> | |||
| <div class="upload-area" id="uploadArea"> | |||
| <i class="fa-solid fa-cloud-upload-alt fa-3x mb-3"></i> | |||
| <h5>Drag & Drop files here</h5> | |||
| <p>or</p> | |||
| <button class="btn btn-primary">Browse Files</button> | |||
| <input type="file" hidden id="fileInput" multiple> | |||
| </div> | |||
| ``` | |||
| ### Date & Time Inputs | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="dateInput" class="form-label">Date</label> | |||
| <input type="date" class="form-control" id="dateInput"> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="timeInput" class="form-label">Time</label> | |||
| <input type="time" class="form-control" id="timeInput"> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="datetimeInput" class="form-label">Date & Time</label> | |||
| <input type="datetime-local" class="form-control" id="datetimeInput"> | |||
| </div> | |||
| ``` | |||
| ### Range Slider | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="rangeInput" class="form-label">Price Range: <span id="rangeValue">50</span></label> | |||
| <input type="range" class="form-range" min="0" max="100" id="rangeInput" value="50"> | |||
| </div> | |||
| <script> | |||
| document.getElementById('rangeInput').addEventListener('input', function(e) { | |||
| document.getElementById('rangeValue').textContent = e.target.value; | |||
| }); | |||
| </script> | |||
| ``` | |||
| ## Form Patterns | |||
| ### Login Form | |||
| ```html | |||
| <form class="needs-validation" novalidate> | |||
| <div class="mb-3"> | |||
| <label for="loginEmail" class="form-label">Email address</label> | |||
| <input type="email" class="form-control" id="loginEmail" required> | |||
| <div class="invalid-feedback"> | |||
| Please enter a valid email address. | |||
| </div> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="loginPassword" class="form-label">Password</label> | |||
| <input type="password" class="form-control" id="loginPassword" required> | |||
| <div class="invalid-feedback"> | |||
| Password is required. | |||
| </div> | |||
| </div> | |||
| <div class="mb-3 form-check"> | |||
| <input type="checkbox" class="form-check-input" id="rememberMe"> | |||
| <label class="form-check-label" for="rememberMe"> | |||
| Remember me | |||
| </label> | |||
| </div> | |||
| <button type="submit" class="btn btn-primary w-100">Sign In</button> | |||
| </form> | |||
| ``` | |||
| ### Multi-Step Form | |||
| ```html | |||
| <form id="multiStepForm"> | |||
| <!-- Step indicators --> | |||
| <div class="step-indicators mb-4"> | |||
| <div class="step active">1</div> | |||
| <div class="step">2</div> | |||
| <div class="step">3</div> | |||
| </div> | |||
| <!-- Step 1 --> | |||
| <div class="form-step active"> | |||
| <h5>Personal Information</h5> | |||
| <input type="text" class="form-control mb-3" placeholder="First Name"> | |||
| <input type="text" class="form-control mb-3" placeholder="Last Name"> | |||
| </div> | |||
| <!-- Step 2 --> | |||
| <div class="form-step"> | |||
| <h5>Contact Details</h5> | |||
| <input type="email" class="form-control mb-3" placeholder="Email"> | |||
| <input type="tel" class="form-control mb-3" placeholder="Phone"> | |||
| </div> | |||
| <!-- Step 3 --> | |||
| <div class="form-step"> | |||
| <h5>Review</h5> | |||
| <p>Please review your information before submitting.</p> | |||
| </div> | |||
| <!-- Navigation --> | |||
| <div class="d-flex justify-content-between"> | |||
| <button type="button" class="btn btn-secondary" id="prevBtn">Previous</button> | |||
| <button type="button" class="btn btn-primary" id="nextBtn">Next</button> | |||
| </div> | |||
| </form> | |||
| ``` | |||
| ## Form Utilities | |||
| ### Floating Labels | |||
| ```html | |||
| <div class="form-floating mb-3"> | |||
| <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com"> | |||
| <label for="floatingInput">Email address</label> | |||
| </div> | |||
| <div class="form-floating"> | |||
| <select class="form-select" id="floatingSelect"> | |||
| <option selected>Select option</option> | |||
| <option value="1">One</option> | |||
| <option value="2">Two</option> | |||
| </select> | |||
| <label for="floatingSelect">Works with selects</label> | |||
| </div> | |||
| ``` | |||
| ### Form Helpers | |||
| ```html | |||
| <div class="mb-3"> | |||
| <label for="inputWithHelp" class="form-label">Password</label> | |||
| <input type="password" class="form-control" id="inputWithHelp"> | |||
| <div class="form-text"> | |||
| Your password must be 8-20 characters long. | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## JavaScript Form Handling | |||
| ### Form Submission | |||
| ```javascript | |||
| // AJAX form submission | |||
| async function submitForm(formElement) { | |||
| const formData = new FormData(formElement); | |||
| const data = Object.fromEntries(formData); | |||
| try { | |||
| const response = await fetch('/api/submit', { | |||
| method: 'POST', | |||
| headers: { | |||
| 'Content-Type': 'application/json', | |||
| }, | |||
| body: JSON.stringify(data) | |||
| }); | |||
| if (response.ok) { | |||
| // Handle success | |||
| showAlert('Form submitted successfully!', 'success'); | |||
| formElement.reset(); | |||
| } else { | |||
| // Handle error | |||
| showAlert('Submission failed. Please try again.', 'danger'); | |||
| } | |||
| } catch (error) { | |||
| console.error('Error:', error); | |||
| showAlert('Network error. Please check your connection.', 'danger'); | |||
| } | |||
| } | |||
| ``` | |||
| ### Dynamic Form Fields | |||
| ```javascript | |||
| // Add/remove form fields dynamically | |||
| function addFormField(container, template) { | |||
| const newField = template.cloneNode(true); | |||
| container.appendChild(newField); | |||
| } | |||
| function removeFormField(button) { | |||
| button.closest('.form-field').remove(); | |||
| } | |||
| ``` | |||
| ## Accessibility | |||
| - Always use labels with form controls | |||
| - Provide clear error messages | |||
| - Use fieldset and legend for grouped inputs | |||
| - Ensure keyboard navigation works | |||
| - Include aria-describedby for help text | |||
| - Test with screen readers | |||
| ## Best Practices | |||
| ### DO: | |||
| - Use appropriate input types | |||
| - Provide clear labels and placeholders | |||
| - Validate on both client and server | |||
| - Show loading states during submission | |||
| - Provide helpful error messages | |||
| - Make forms mobile-friendly | |||
| ### DON'T: | |||
| - Don't rely only on color for feedback | |||
| - Don't auto-focus without reason | |||
| - Don't disable browser autofill | |||
| - Don't use placeholder as label | |||
| - Don't make forms too long | |||
| @ -0,0 +1,167 @@ | |||
| # Components Overview | |||
| Concept includes a comprehensive set of reusable components built on Bootstrap 5. All components are jQuery-free and use modern JavaScript. | |||
| ## Component Structure | |||
| Components follow a consistent pattern: | |||
| ```javascript | |||
| // JavaScript initialization | |||
| import { ComponentName } from './components/component-name.js'; | |||
| // Initialize on DOM ready | |||
| document.addEventListener('DOMContentLoaded', () => { | |||
| ComponentName.init(); | |||
| }); | |||
| ``` | |||
| ## Available Components | |||
| ### Core Components | |||
| - **[Buttons](buttons.md)** - Button styles, sizes, and states | |||
| - **[Cards](cards.md)** - Content containers with various layouts | |||
| - **[Forms](forms.md)** - Form controls and validation | |||
| - **[Tables](tables.md)** - Data tables with sorting and filtering | |||
| ### Navigation | |||
| - **[Sidebar](../layout/sidebar.md)** - Collapsible navigation sidebar | |||
| - **[Header](../layout/header.md)** - Top navigation bar | |||
| - **[Breadcrumbs](#breadcrumbs)** - Page navigation trail | |||
| ### Feedback | |||
| - **[Alerts](#alerts)** - Dismissible alert messages | |||
| - **[Modals](#modals)** - Dialog boxes | |||
| - **[Toasts](#toasts)** - Non-blocking notifications | |||
| ### Data Display | |||
| - **[Charts](charts.md)** - Chart.js integration | |||
| - **[Progress](#progress)** - Progress bars and indicators | |||
| - **[Badges](#badges)** - Status indicators | |||
| ## Quick Examples | |||
| ### Basic Card | |||
| ```html | |||
| <div class="card"> | |||
| <div class="card-header"> | |||
| <h5 class="card-title">Card Title</h5> | |||
| </div> | |||
| <div class="card-body"> | |||
| <p class="card-text">Card content goes here.</p> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ### Alert with Dismiss | |||
| ```html | |||
| <div class="alert alert-warning alert-dismissible fade show" role="alert"> | |||
| <strong>Warning!</strong> This is a warning alert. | |||
| <button type="button" class="btn-close" data-bs-dismiss="alert"></button> | |||
| </div> | |||
| ``` | |||
| ### Modal Trigger | |||
| ```html | |||
| <!-- Button trigger --> | |||
| <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal"> | |||
| Launch modal | |||
| </button> | |||
| <!-- Modal --> | |||
| <div class="modal fade" id="exampleModal" tabindex="-1"> | |||
| <div class="modal-dialog"> | |||
| <div class="modal-content"> | |||
| <div class="modal-header"> | |||
| <h5 class="modal-title">Modal title</h5> | |||
| <button type="button" class="btn-close" data-bs-dismiss="modal"></button> | |||
| </div> | |||
| <div class="modal-body"> | |||
| Modal content | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Component Initialization | |||
| ### Auto-initialization | |||
| Most Bootstrap components initialize automatically with data attributes: | |||
| ```html | |||
| <!-- Tooltip --> | |||
| <button type="button" data-bs-toggle="tooltip" title="Tooltip text"> | |||
| Hover me | |||
| </button> | |||
| <!-- Popover --> | |||
| <button type="button" data-bs-toggle="popover" data-bs-content="Popover content"> | |||
| Click me | |||
| </button> | |||
| ``` | |||
| ### Manual Initialization | |||
| For dynamic content, initialize components manually: | |||
| ```javascript | |||
| // Initialize all tooltips | |||
| const tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]'); | |||
| tooltips.forEach(el => new bootstrap.Tooltip(el)); | |||
| // Initialize specific modal | |||
| const modal = new bootstrap.Modal(document.getElementById('myModal')); | |||
| modal.show(); | |||
| ``` | |||
| ## Custom Components | |||
| ### Creating Custom Components | |||
| ```javascript | |||
| // components/custom-component.js | |||
| export class CustomComponent { | |||
| constructor(element) { | |||
| this.element = element; | |||
| this.init(); | |||
| } | |||
| init() { | |||
| // Component logic | |||
| } | |||
| static init(selector = '[data-custom-component]') { | |||
| document.querySelectorAll(selector).forEach(el => { | |||
| new CustomComponent(el); | |||
| }); | |||
| } | |||
| } | |||
| ``` | |||
| ## Component Guidelines | |||
| ### Accessibility | |||
| - All interactive components must be keyboard accessible | |||
| - Use proper ARIA attributes | |||
| - Maintain focus management | |||
| - Provide screen reader support | |||
| ### Performance | |||
| - Lazy load heavy components | |||
| - Use event delegation for dynamic content | |||
| - Minimize DOM manipulation | |||
| - Debounce/throttle expensive operations | |||
| ### Mobile Support | |||
| - Ensure touch-friendly interactions | |||
| - Test on various screen sizes | |||
| - Consider mobile-specific behaviors | |||
| - Optimize for performance | |||
| ## Next Steps | |||
| Explore specific component documentation: | |||
| 1. **[Buttons](buttons.md)** - All button variants | |||
| 2. **[Cards](cards.md)** - Card layouts and options | |||
| 3. **[Forms](forms.md)** - Form building blocks | |||
| 4. **[Tables](tables.md)** - Data presentation | |||
| @ -0,0 +1,463 @@ | |||
| # Tables | |||
| Tables are essential for displaying structured data. Concept provides both basic Bootstrap tables and advanced DataTables integration. | |||
| ## Basic Tables | |||
| ### Simple Table | |||
| ```html | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th scope="col">#</th> | |||
| <th scope="col">Name</th> | |||
| <th scope="col">Email</th> | |||
| <th scope="col">Status</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <th scope="row">1</th> | |||
| <td>John Doe</td> | |||
| <td>john@example.com</td> | |||
| <td><span class="badge bg-success">Active</span></td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| ``` | |||
| ### Table Variants | |||
| ```html | |||
| <!-- Striped rows --> | |||
| <table class="table table-striped"> | |||
| <!-- table content --> | |||
| </table> | |||
| <!-- Bordered table --> | |||
| <table class="table table-bordered"> | |||
| <!-- table content --> | |||
| </table> | |||
| <!-- Hover effect --> | |||
| <table class="table table-hover"> | |||
| <!-- table content --> | |||
| </table> | |||
| <!-- Small table --> | |||
| <table class="table table-sm"> | |||
| <!-- table content --> | |||
| </table> | |||
| ``` | |||
| ### Responsive Tables | |||
| ```html | |||
| <!-- Always responsive --> | |||
| <div class="table-responsive"> | |||
| <table class="table"> | |||
| <!-- table content --> | |||
| </table> | |||
| </div> | |||
| <!-- Responsive at specific breakpoints --> | |||
| <div class="table-responsive-lg"> | |||
| <table class="table"> | |||
| <!-- table content --> | |||
| </table> | |||
| </div> | |||
| ``` | |||
| ## DataTables Integration | |||
| ### Basic DataTable | |||
| ```html | |||
| <table id="dataTable" class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Name</th> | |||
| <th>Position</th> | |||
| <th>Office</th> | |||
| <th>Age</th> | |||
| <th>Start date</th> | |||
| <th>Salary</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <!-- table rows --> | |||
| </tbody> | |||
| </table> | |||
| <script> | |||
| import DataTable from 'datatables.net-bs5'; | |||
| document.addEventListener('DOMContentLoaded', function() { | |||
| new DataTable('#dataTable'); | |||
| }); | |||
| </script> | |||
| ``` | |||
| ### DataTable with Options | |||
| ```javascript | |||
| new DataTable('#advancedTable', { | |||
| // Pagination | |||
| pageLength: 25, | |||
| lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]], | |||
| // Sorting | |||
| order: [[1, 'asc']], | |||
| // Search | |||
| searching: true, | |||
| // Info | |||
| info: true, | |||
| // Responsive | |||
| responsive: true, | |||
| // Language | |||
| language: { | |||
| search: "Search:", | |||
| lengthMenu: "Show _MENU_ entries", | |||
| info: "Showing _START_ to _END_ of _TOTAL_ entries", | |||
| paginate: { | |||
| first: "First", | |||
| last: "Last", | |||
| next: "Next", | |||
| previous: "Previous" | |||
| } | |||
| } | |||
| }); | |||
| ``` | |||
| ### Server-Side Processing | |||
| ```javascript | |||
| new DataTable('#serverTable', { | |||
| processing: true, | |||
| serverSide: true, | |||
| ajax: { | |||
| url: '/api/data', | |||
| type: 'POST', | |||
| data: function(d) { | |||
| // Add custom parameters | |||
| d.customParam = 'value'; | |||
| } | |||
| }, | |||
| columns: [ | |||
| { data: 'name' }, | |||
| { data: 'email' }, | |||
| { data: 'status' }, | |||
| { | |||
| data: 'id', | |||
| render: function(data) { | |||
| return ` | |||
| <button class="btn btn-sm btn-primary" onclick="editRecord(${data})"> | |||
| <i class="fa-solid fa-edit"></i> | |||
| </button> | |||
| <button class="btn btn-sm btn-danger" onclick="deleteRecord(${data})"> | |||
| <i class="fa-solid fa-trash"></i> | |||
| </button> | |||
| `; | |||
| } | |||
| } | |||
| ] | |||
| }); | |||
| ``` | |||
| ## Table Patterns | |||
| ### Table with Actions | |||
| ```html | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th> | |||
| <input type="checkbox" class="form-check-input" id="selectAll"> | |||
| </th> | |||
| <th>Name</th> | |||
| <th>Email</th> | |||
| <th>Role</th> | |||
| <th>Actions</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <td> | |||
| <input type="checkbox" class="form-check-input row-checkbox"> | |||
| </td> | |||
| <td>John Doe</td> | |||
| <td>john@example.com</td> | |||
| <td>Admin</td> | |||
| <td> | |||
| <div class="btn-group btn-group-sm"> | |||
| <button class="btn btn-outline-primary"> | |||
| <i class="fa-solid fa-eye"></i> | |||
| </button> | |||
| <button class="btn btn-outline-secondary"> | |||
| <i class="fa-solid fa-edit"></i> | |||
| </button> | |||
| <button class="btn btn-outline-danger"> | |||
| <i class="fa-solid fa-trash"></i> | |||
| </button> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| <script> | |||
| // Select all functionality | |||
| document.getElementById('selectAll').addEventListener('change', function() { | |||
| const checkboxes = document.querySelectorAll('.row-checkbox'); | |||
| checkboxes.forEach(cb => cb.checked = this.checked); | |||
| }); | |||
| </script> | |||
| ``` | |||
| ### Expandable Rows | |||
| ```html | |||
| <table class="table"> | |||
| <tbody> | |||
| <tr class="expandable-row" data-target="#details1"> | |||
| <td><i class="fa-solid fa-chevron-right"></i></td> | |||
| <td>Order #1234</td> | |||
| <td>$150.00</td> | |||
| <td>Completed</td> | |||
| </tr> | |||
| <tr id="details1" class="collapse"> | |||
| <td colspan="4"> | |||
| <div class="p-3"> | |||
| <h6>Order Details</h6> | |||
| <p>Additional information about the order...</p> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| <script> | |||
| document.querySelectorAll('.expandable-row').forEach(row => { | |||
| row.addEventListener('click', function() { | |||
| const target = document.querySelector(this.dataset.target); | |||
| const icon = this.querySelector('i'); | |||
| if (target.classList.contains('show')) { | |||
| target.classList.remove('show'); | |||
| icon.classList.replace('fa-chevron-down', 'fa-chevron-right'); | |||
| } else { | |||
| target.classList.add('show'); | |||
| icon.classList.replace('fa-chevron-right', 'fa-chevron-down'); | |||
| } | |||
| }); | |||
| }); | |||
| </script> | |||
| ``` | |||
| ### Editable Table | |||
| ```html | |||
| <table class="table" id="editableTable"> | |||
| <thead> | |||
| <tr> | |||
| <th>Product</th> | |||
| <th>Price</th> | |||
| <th>Quantity</th> | |||
| <th>Total</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <td contenteditable="true">Product Name</td> | |||
| <td contenteditable="true" class="price">10.00</td> | |||
| <td contenteditable="true" class="quantity">1</td> | |||
| <td class="total">10.00</td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| <script> | |||
| // Calculate totals on edit | |||
| document.querySelectorAll('#editableTable td[contenteditable]').forEach(cell => { | |||
| cell.addEventListener('input', function() { | |||
| const row = this.closest('tr'); | |||
| const price = parseFloat(row.querySelector('.price').textContent) || 0; | |||
| const quantity = parseInt(row.querySelector('.quantity').textContent) || 0; | |||
| row.querySelector('.total').textContent = (price * quantity).toFixed(2); | |||
| }); | |||
| }); | |||
| </script> | |||
| ``` | |||
| ## Advanced Features | |||
| ### Export Buttons | |||
| ```javascript | |||
| new DataTable('#exportTable', { | |||
| dom: 'Bfrtip', | |||
| buttons: [ | |||
| 'copy', | |||
| 'csv', | |||
| 'excel', | |||
| 'pdf', | |||
| { | |||
| extend: 'print', | |||
| text: '<i class="fa-solid fa-print"></i> Print', | |||
| className: 'btn btn-secondary' | |||
| } | |||
| ] | |||
| }); | |||
| ``` | |||
| ### Column Visibility | |||
| ```javascript | |||
| new DataTable('#columnToggleTable', { | |||
| dom: 'Bfrtip', | |||
| buttons: [ | |||
| { | |||
| extend: 'colvis', | |||
| text: 'Columns', | |||
| className: 'btn btn-secondary' | |||
| } | |||
| ], | |||
| columnDefs: [ | |||
| { | |||
| targets: [2, 3], | |||
| visible: false | |||
| } | |||
| ] | |||
| }); | |||
| ``` | |||
| ### Custom Filtering | |||
| ```html | |||
| <div class="row mb-3"> | |||
| <div class="col-md-4"> | |||
| <select class="form-select" id="statusFilter"> | |||
| <option value="">All Status</option> | |||
| <option value="Active">Active</option> | |||
| <option value="Inactive">Inactive</option> | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <table id="filterTable" class="table"> | |||
| <!-- table content --> | |||
| </table> | |||
| <script> | |||
| const table = new DataTable('#filterTable'); | |||
| // Custom filter | |||
| document.getElementById('statusFilter').addEventListener('change', function() { | |||
| table.column(3).search(this.value).draw(); | |||
| }); | |||
| // Date range filter | |||
| $.fn.dataTable.ext.search.push(function(settings, data, dataIndex) { | |||
| const min = $('#minDate').val(); | |||
| const max = $('#maxDate').val(); | |||
| const date = data[4]; // Date column | |||
| if (!min && !max) return true; | |||
| if (!min && date <= max) return true; | |||
| if (min <= date && !max) return true; | |||
| if (min <= date && date <= max) return true; | |||
| return false; | |||
| }); | |||
| </script> | |||
| ``` | |||
| ## Table Styling | |||
| ### Custom Table Styles | |||
| ```scss | |||
| // Compact table | |||
| .table-compact { | |||
| td, th { | |||
| padding: 0.5rem; | |||
| font-size: 0.875rem; | |||
| } | |||
| } | |||
| // Fixed header | |||
| .table-fixed-header { | |||
| thead { | |||
| position: sticky; | |||
| top: 0; | |||
| background-color: $white; | |||
| z-index: 10; | |||
| box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1); | |||
| } | |||
| } | |||
| // Highlight on hover | |||
| .table-highlight tbody tr:hover { | |||
| background-color: rgba($primary, 0.05); | |||
| cursor: pointer; | |||
| } | |||
| ``` | |||
| ## Performance Optimization | |||
| ### Virtual Scrolling | |||
| ```javascript | |||
| new DataTable('#largeTable', { | |||
| scrollY: '400px', | |||
| scrollCollapse: true, | |||
| scroller: true, | |||
| deferRender: true, | |||
| ajax: 'large-dataset.json' | |||
| }); | |||
| ``` | |||
| ### Lazy Loading | |||
| ```javascript | |||
| let page = 1; | |||
| const pageSize = 50; | |||
| function loadMoreRows() { | |||
| fetch(`/api/data?page=${page}&size=${pageSize}`) | |||
| .then(response => response.json()) | |||
| .then(data => { | |||
| const tbody = document.querySelector('#infiniteTable tbody'); | |||
| data.forEach(row => { | |||
| tbody.insertAdjacentHTML('beforeend', createTableRow(row)); | |||
| }); | |||
| page++; | |||
| }); | |||
| } | |||
| // Intersection Observer for infinite scroll | |||
| const observer = new IntersectionObserver(entries => { | |||
| if (entries[0].isIntersecting) { | |||
| loadMoreRows(); | |||
| } | |||
| }); | |||
| observer.observe(document.querySelector('#loadMoreTrigger')); | |||
| ``` | |||
| ## Accessibility | |||
| - Use proper table structure with thead, tbody | |||
| - Include scope attributes on th elements | |||
| - Provide table captions when needed | |||
| - Ensure keyboard navigation works | |||
| - Use aria-label for action buttons | |||
| - Maintain focus management | |||
| ## Best Practices | |||
| ### DO: | |||
| - Use semantic HTML table elements | |||
| - Make tables responsive | |||
| - Provide sorting/filtering for large datasets | |||
| - Include loading states | |||
| - Show empty states when no data | |||
| - Use appropriate column widths | |||
| ### DON'T: | |||
| - Don't use tables for layout | |||
| - Don't load thousands of rows at once | |||
| - Don't forget mobile experience | |||
| - Don't make cells too cramped | |||
| - Don't use tables for simple lists | |||
| @ -0,0 +1,653 @@ | |||
| # Color System | |||
| Concept provides a comprehensive color system built on Bootstrap 5's color utilities, with additional custom colors and advanced features for creating beautiful, accessible interfaces. | |||
| ## Color Palette | |||
| ### Theme Colors | |||
| The primary theme colors are used throughout the template: | |||
| ```scss | |||
| // Primary theme colors | |||
| $primary: #5969ff; // Royal Blue | |||
| $secondary: #6c757d; // Gray | |||
| $success: #28a745; // Green | |||
| $info: #17a2b8; // Cyan | |||
| $warning: #ffc107; // Amber | |||
| $danger: #dc3545; // Red | |||
| $light: #f8f9fa; // Light Gray | |||
| $dark: #343a40; // Dark Gray | |||
| ``` | |||
| <div class="color-palette"> | |||
| <div class="color-swatch" style="background: #5969ff;"> | |||
| <span>Primary</span> | |||
| <code>#5969ff</code> | |||
| </div> | |||
| <div class="color-swatch" style="background: #6c757d;"> | |||
| <span>Secondary</span> | |||
| <code>#6c757d</code> | |||
| </div> | |||
| <div class="color-swatch" style="background: #28a745;"> | |||
| <span>Success</span> | |||
| <code>#28a745</code> | |||
| </div> | |||
| <div class="color-swatch" style="background: #17a2b8;"> | |||
| <span>Info</span> | |||
| <code>#17a2b8</code> | |||
| </div> | |||
| <div class="color-swatch" style="background: #ffc107;"> | |||
| <span>Warning</span> | |||
| <code>#ffc107</code> | |||
| </div> | |||
| <div class="color-swatch" style="background: #dc3545;"> | |||
| <span>Danger</span> | |||
| <code>#dc3545</code> | |||
| </div> | |||
| </div> | |||
| ### Extended Colors | |||
| Additional colors for more design flexibility: | |||
| ```scss | |||
| // Extended color palette | |||
| $indigo: #6610f2; | |||
| $purple: #6f42c1; | |||
| $pink: #e83e8c; | |||
| $red: #dc3545; | |||
| $orange: #fd7e14; | |||
| $yellow: #ffc107; | |||
| $green: #28a745; | |||
| $teal: #20c997; | |||
| $cyan: #17a2b8; | |||
| ``` | |||
| ### Gray Scale | |||
| Complete grayscale for subtle variations: | |||
| ```scss | |||
| $white: #ffffff; | |||
| $gray-100: #f8f9fa; | |||
| $gray-200: #e9ecef; | |||
| $gray-300: #dee2e6; | |||
| $gray-400: #ced4da; | |||
| $gray-500: #adb5bd; | |||
| $gray-600: #6c757d; | |||
| $gray-700: #495057; | |||
| $gray-800: #343a40; | |||
| $gray-900: #212529; | |||
| $black: #000000; | |||
| ``` | |||
| ## Color Utilities | |||
| ### Text Colors | |||
| Apply colors to text using utility classes: | |||
| ```html | |||
| <!-- Theme colors --> | |||
| <p class="text-primary">Primary text color</p> | |||
| <p class="text-secondary">Secondary text color</p> | |||
| <p class="text-success">Success text color</p> | |||
| <p class="text-danger">Danger text color</p> | |||
| <p class="text-warning">Warning text color</p> | |||
| <p class="text-info">Info text color</p> | |||
| <p class="text-light bg-dark">Light text color</p> | |||
| <p class="text-dark">Dark text color</p> | |||
| <!-- Grayscale --> | |||
| <p class="text-black">Black text</p> | |||
| <p class="text-white bg-dark">White text</p> | |||
| <p class="text-black-50">50% opacity black</p> | |||
| <p class="text-white-50 bg-dark">50% opacity white</p> | |||
| <!-- Body and muted --> | |||
| <p class="text-body">Default body text</p> | |||
| <p class="text-muted">Muted text color</p> | |||
| ``` | |||
| ### Background Colors | |||
| Apply background colors with optional text color adjustment: | |||
| ```html | |||
| <!-- Basic backgrounds --> | |||
| <div class="bg-primary text-white p-3">Primary background</div> | |||
| <div class="bg-secondary text-white p-3">Secondary background</div> | |||
| <div class="bg-success text-white p-3">Success background</div> | |||
| <div class="bg-danger text-white p-3">Danger background</div> | |||
| <div class="bg-warning text-dark p-3">Warning background</div> | |||
| <div class="bg-info text-white p-3">Info background</div> | |||
| <div class="bg-light p-3">Light background</div> | |||
| <div class="bg-dark text-white p-3">Dark background</div> | |||
| <!-- Gradient backgrounds --> | |||
| <div class="bg-gradient-primary text-white p-3">Primary gradient</div> | |||
| <div class="bg-gradient-secondary text-white p-3">Secondary gradient</div> | |||
| <!-- Subtle backgrounds --> | |||
| <div class="bg-primary-subtle p-3">Subtle primary background</div> | |||
| <div class="bg-success-subtle p-3">Subtle success background</div> | |||
| ``` | |||
| ### Border Colors | |||
| Style borders with color utilities: | |||
| ```html | |||
| <!-- Border colors --> | |||
| <div class="border border-primary p-3">Primary border</div> | |||
| <div class="border border-success p-3">Success border</div> | |||
| <div class="border border-danger p-3">Danger border</div> | |||
| <!-- Individual border sides --> | |||
| <div class="border-top border-primary p-3">Top border only</div> | |||
| <div class="border-end border-success p-3">Right border only</div> | |||
| <div class="border-bottom border-warning p-3">Bottom border only</div> | |||
| <div class="border-start border-info p-3">Left border only</div> | |||
| <!-- Border width variations --> | |||
| <div class="border border-3 border-primary p-3">Thick primary border</div> | |||
| <div class="border border-5 border-danger p-3">Extra thick danger border</div> | |||
| ``` | |||
| ## Custom Color Classes | |||
| ### Brand Colors | |||
| Define and use custom brand colors: | |||
| ```scss | |||
| // Define custom colors | |||
| $brand-colors: ( | |||
| "brand-primary": #1a73e8, | |||
| "brand-secondary": #ea4335, | |||
| "brand-accent": #34a853, | |||
| "brand-neutral": #5f6368 | |||
| ); | |||
| // Generate utilities | |||
| @each $name, $color in $brand-colors { | |||
| .text-#{$name} { | |||
| color: $color !important; | |||
| } | |||
| .bg-#{$name} { | |||
| background-color: $color !important; | |||
| } | |||
| .border-#{$name} { | |||
| border-color: $color !important; | |||
| } | |||
| } | |||
| ``` | |||
| ### Social Media Colors | |||
| Pre-defined social media brand colors: | |||
| ```scss | |||
| // Social media colors | |||
| $social-colors: ( | |||
| "facebook": #1877f2, | |||
| "twitter": #1da1f2, | |||
| "instagram": #e4405f, | |||
| "linkedin": #0077b5, | |||
| "youtube": #ff0000, | |||
| "github": #181717, | |||
| "whatsapp": #25d366, | |||
| "telegram": #0088cc, | |||
| "discord": #5865f2, | |||
| "slack": #4a154b | |||
| ); | |||
| // Usage | |||
| .btn-facebook { | |||
| background-color: map-get($social-colors, "facebook"); | |||
| color: white; | |||
| &:hover { | |||
| background-color: darken(map-get($social-colors, "facebook"), 10%); | |||
| } | |||
| } | |||
| ``` | |||
| ## Color Functions | |||
| ### Sass Color Functions | |||
| Use Sass functions to manipulate colors: | |||
| ```scss | |||
| // Lighten and darken | |||
| .custom-button { | |||
| background-color: $primary; | |||
| &:hover { | |||
| background-color: lighten($primary, 10%); | |||
| } | |||
| &:active { | |||
| background-color: darken($primary, 10%); | |||
| } | |||
| } | |||
| // Adjust hue, saturation, lightness | |||
| .color-variations { | |||
| .hue-shift { | |||
| background-color: adjust-hue($primary, 45deg); | |||
| } | |||
| .saturated { | |||
| background-color: saturate($primary, 20%); | |||
| } | |||
| .desaturated { | |||
| background-color: desaturate($primary, 20%); | |||
| } | |||
| } | |||
| // Mix colors | |||
| .mixed-color { | |||
| background-color: mix($primary, $secondary, 50%); | |||
| } | |||
| // Transparency | |||
| .transparent-overlay { | |||
| background-color: rgba($primary, 0.8); | |||
| // or | |||
| background-color: transparentize($primary, 0.2); | |||
| } | |||
| ``` | |||
| ### Custom Color Functions | |||
| Create reusable color functions: | |||
| ```scss | |||
| // Tint function (mix with white) | |||
| @function tint($color, $percentage) { | |||
| @return mix(white, $color, $percentage); | |||
| } | |||
| // Shade function (mix with black) | |||
| @function shade($color, $percentage) { | |||
| @return mix(black, $color, $percentage); | |||
| } | |||
| // Usage | |||
| .tinted-primary { | |||
| background-color: tint($primary, 20%); | |||
| } | |||
| .shaded-primary { | |||
| background-color: shade($primary, 20%); | |||
| } | |||
| // Color contrast function | |||
| @function color-contrast($color) { | |||
| $r: red($color); | |||
| $g: green($color); | |||
| $b: blue($color); | |||
| $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000; | |||
| @if ($yiq >= 150) { | |||
| @return $dark; | |||
| } @else { | |||
| @return $white; | |||
| } | |||
| } | |||
| // Auto text color based on background | |||
| .dynamic-text { | |||
| background-color: $primary; | |||
| color: color-contrast($primary); | |||
| } | |||
| ``` | |||
| ## Color Schemes | |||
| ### Monochromatic Scheme | |||
| Using variations of a single color: | |||
| ```scss | |||
| // Generate monochromatic palette | |||
| $mono-base: $primary; | |||
| $mono-colors: ( | |||
| "mono-100": tint($mono-base, 80%), | |||
| "mono-200": tint($mono-base, 60%), | |||
| "mono-300": tint($mono-base, 40%), | |||
| "mono-400": tint($mono-base, 20%), | |||
| "mono-500": $mono-base, | |||
| "mono-600": shade($mono-base, 20%), | |||
| "mono-700": shade($mono-base, 40%), | |||
| "mono-800": shade($mono-base, 60%), | |||
| "mono-900": shade($mono-base, 80%) | |||
| ); | |||
| ``` | |||
| ### Complementary Scheme | |||
| Using opposite colors on the color wheel: | |||
| ```scss | |||
| // Complementary colors | |||
| $base-color: $primary; | |||
| $complement: adjust-hue($base-color, 180deg); | |||
| .complementary-scheme { | |||
| .primary-element { | |||
| background-color: $base-color; | |||
| } | |||
| .accent-element { | |||
| background-color: $complement; | |||
| } | |||
| } | |||
| ``` | |||
| ### Triadic Scheme | |||
| Three evenly spaced colors: | |||
| ```scss | |||
| // Triadic color scheme | |||
| $triadic-1: $primary; | |||
| $triadic-2: adjust-hue($primary, 120deg); | |||
| $triadic-3: adjust-hue($primary, 240deg); | |||
| .triadic-scheme { | |||
| .color-1 { background-color: $triadic-1; } | |||
| .color-2 { background-color: $triadic-2; } | |||
| .color-3 { background-color: $triadic-3; } | |||
| } | |||
| ``` | |||
| ## Gradients | |||
| ### Linear Gradients | |||
| ```scss | |||
| // Gradient utilities | |||
| .bg-gradient-primary-secondary { | |||
| background: linear-gradient(135deg, $primary 0%, $secondary 100%); | |||
| } | |||
| .bg-gradient-rainbow { | |||
| background: linear-gradient( | |||
| 45deg, | |||
| #ff0000 0%, | |||
| #ff7f00 14.28%, | |||
| #ffff00 28.56%, | |||
| #00ff00 42.84%, | |||
| #0000ff 57.12%, | |||
| #4b0082 71.4%, | |||
| #9400d3 85.68%, | |||
| #ff0000 100% | |||
| ); | |||
| } | |||
| // Gradient text | |||
| .gradient-text { | |||
| background: linear-gradient(135deg, $primary 0%, $info 100%); | |||
| -webkit-background-clip: text; | |||
| -webkit-text-fill-color: transparent; | |||
| background-clip: text; | |||
| } | |||
| ``` | |||
| ### Radial Gradients | |||
| ```scss | |||
| // Radial gradient examples | |||
| .bg-radial-gradient { | |||
| background: radial-gradient(circle at center, $primary 0%, $dark 100%); | |||
| } | |||
| .bg-radial-light { | |||
| background: radial-gradient( | |||
| ellipse at top, | |||
| rgba($primary, 0.1) 0%, | |||
| transparent 70% | |||
| ); | |||
| } | |||
| ``` | |||
| ## Accessibility | |||
| ### Color Contrast | |||
| Ensure sufficient contrast for accessibility: | |||
| ```scss | |||
| // WCAG AA compliant contrasts | |||
| $accessible-pairs: ( | |||
| ($white, $gray-800), // 12.63:1 | |||
| ($white, $primary), // 4.5:1 | |||
| ($white, $danger), // 4.52:1 | |||
| ($dark, $warning), // 8.59:1 | |||
| ($white, $success), // 5.15:1 | |||
| ); | |||
| // Contrast checking mixin | |||
| @mixin check-contrast($bg, $text) { | |||
| background-color: $bg; | |||
| color: $text; | |||
| // Add warning for development | |||
| @if (contrast-ratio($bg, $text) < 4.5) { | |||
| @warn "Low contrast ratio between #{$bg} and #{$text}"; | |||
| } | |||
| } | |||
| ``` | |||
| ### Color Blind Friendly | |||
| Colors that work for color blind users: | |||
| ```scss | |||
| // Color blind friendly palette | |||
| $cb-friendly: ( | |||
| "blue": #0173B2, | |||
| "orange": #F0A041, | |||
| "green": #009E73, | |||
| "yellow": #FED439, | |||
| "purple": #CC79A7, | |||
| "red": #D55E00, | |||
| "gray": #999999 | |||
| ); | |||
| // Safe color combinations | |||
| .cb-safe-primary { | |||
| background-color: map-get($cb-friendly, "blue"); | |||
| color: white; | |||
| } | |||
| .cb-safe-secondary { | |||
| background-color: map-get($cb-friendly, "orange"); | |||
| color: black; | |||
| } | |||
| ``` | |||
| ## Color Variables in CSS | |||
| ### CSS Custom Properties | |||
| Use CSS variables for dynamic theming: | |||
| ```scss | |||
| // Define CSS variables | |||
| :root { | |||
| --color-primary: #{$primary}; | |||
| --color-secondary: #{$secondary}; | |||
| --color-success: #{$success}; | |||
| --color-danger: #{$danger}; | |||
| --color-warning: #{$warning}; | |||
| --color-info: #{$info}; | |||
| // Semantic colors | |||
| --color-text: #{$gray-900}; | |||
| --color-text-muted: #{$gray-600}; | |||
| --color-background: #{$white}; | |||
| --color-surface: #{$gray-100}; | |||
| --color-border: #{$gray-300}; | |||
| } | |||
| // Dark mode | |||
| [data-theme="dark"] { | |||
| --color-text: #{$gray-100}; | |||
| --color-text-muted: #{$gray-400}; | |||
| --color-background: #{$gray-900}; | |||
| --color-surface: #{$gray-800}; | |||
| --color-border: #{$gray-700}; | |||
| } | |||
| // Usage | |||
| .component { | |||
| color: var(--color-text); | |||
| background-color: var(--color-surface); | |||
| border: 1px solid var(--color-border); | |||
| } | |||
| ``` | |||
| ## Color Tools | |||
| ### Color Picker Component | |||
| ```html | |||
| <!-- Color picker input --> | |||
| <div class="color-picker-group"> | |||
| <label for="theme-color">Choose Theme Color</label> | |||
| <div class="input-group"> | |||
| <input type="color" | |||
| class="form-control form-control-color" | |||
| id="theme-color" | |||
| value="#5969ff"> | |||
| <input type="text" | |||
| class="form-control" | |||
| value="#5969ff" | |||
| pattern="^#[0-9A-F]{6}$"> | |||
| </div> | |||
| </div> | |||
| <!-- Color palette selector --> | |||
| <div class="color-palette-selector"> | |||
| <div class="color-option" | |||
| data-color="#5969ff" | |||
| style="background-color: #5969ff;"></div> | |||
| <div class="color-option" | |||
| data-color="#28a745" | |||
| style="background-color: #28a745;"></div> | |||
| <div class="color-option" | |||
| data-color="#dc3545" | |||
| style="background-color: #dc3545;"></div> | |||
| </div> | |||
| ``` | |||
| ### JavaScript Color Utilities | |||
| ```javascript | |||
| // Color manipulation utilities | |||
| class ColorUtils { | |||
| // Convert hex to RGB | |||
| static hexToRgb(hex) { | |||
| const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); | |||
| return result ? { | |||
| r: parseInt(result[1], 16), | |||
| g: parseInt(result[2], 16), | |||
| b: parseInt(result[3], 16) | |||
| } : null; | |||
| } | |||
| // Convert RGB to hex | |||
| static rgbToHex(r, g, b) { | |||
| return "#" + ((1 << 24) + (r << 16) + (g << 8) + b) | |||
| .toString(16).slice(1); | |||
| } | |||
| // Calculate luminance | |||
| static getLuminance(hex) { | |||
| const rgb = this.hexToRgb(hex); | |||
| const a = [rgb.r, rgb.g, rgb.b].map(v => { | |||
| v /= 255; | |||
| return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); | |||
| }); | |||
| return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2]; | |||
| } | |||
| // Get contrast ratio | |||
| static getContrastRatio(color1, color2) { | |||
| const lum1 = this.getLuminance(color1); | |||
| const lum2 = this.getLuminance(color2); | |||
| const brightest = Math.max(lum1, lum2); | |||
| const darkest = Math.min(lum1, lum2); | |||
| return (brightest + 0.05) / (darkest + 0.05); | |||
| } | |||
| // Generate color palette | |||
| static generatePalette(baseColor, count = 9) { | |||
| const palette = []; | |||
| const rgb = this.hexToRgb(baseColor); | |||
| for (let i = 0; i < count; i++) { | |||
| const factor = i / (count - 1); | |||
| const r = Math.round(rgb.r + (255 - rgb.r) * factor); | |||
| const g = Math.round(rgb.g + (255 - rgb.g) * factor); | |||
| const b = Math.round(rgb.b + (255 - rgb.b) * factor); | |||
| palette.push(this.rgbToHex(r, g, b)); | |||
| } | |||
| return palette; | |||
| } | |||
| } | |||
| ``` | |||
| ## Best Practices | |||
| ### DO: | |||
| - ✅ Use semantic color names (primary, success, danger) | |||
| - ✅ Maintain consistent color usage across the app | |||
| - ✅ Test color combinations for accessibility | |||
| - ✅ Use color functions for variations | |||
| - ✅ Document custom color choices | |||
| - ✅ Consider color blind users | |||
| ### DON'T: | |||
| - ❌ Use colors only to convey information | |||
| - ❌ Create low contrast combinations | |||
| - ❌ Mix too many colors (stick to 3-5 main colors) | |||
| - ❌ Use pure black (#000) for text | |||
| - ❌ Ignore dark mode compatibility | |||
| - ❌ Hardcode color values | |||
| ## Color Resources | |||
| ### Tools | |||
| - [Adobe Color](https://color.adobe.com) - Color scheme generator | |||
| - [Coolors](https://coolors.co) - Color palette generator | |||
| - [Contrast Checker](https://webaim.org/resources/contrastchecker/) - WCAG compliance | |||
| - [Colorblindly](https://chrome.google.com/webstore/detail/colorblindly/) - Chrome extension | |||
| ### Guidelines | |||
| - [WCAG Color Contrast](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) | |||
| - [Material Design Color](https://material.io/design/color/) | |||
| - [Apple Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/color) | |||
| ## Next Steps | |||
| Continue customizing Concept: | |||
| 1. **[Component Styling](components.md)** - Apply colors to components | |||
| 2. **[Theming Guide](theming.md)** - Create color themes | |||
| 3. **[Dark Mode](../advanced/dark-mode.md)** - Implement dark mode | |||
| 4. **[Accessibility](../advanced/accessibility.md)** - Color accessibility | |||
| --- | |||
| Colors bring life to your interface. Use them wisely to create beautiful, accessible, and meaningful experiences! 🎨 | |||
| @ -0,0 +1,287 @@ | |||
| # Customization Overview | |||
| Concept is built with customization in mind. This guide provides an overview of all the ways you can make the template your own. | |||
| ## Customization Approaches | |||
| ### 1. Quick Customizations | |||
| - Change colors and fonts | |||
| - Modify spacing and sizes | |||
| - Toggle features on/off | |||
| - Adjust layouts | |||
| ### 2. Intermediate Customizations | |||
| - Create custom themes | |||
| - Add new components | |||
| - Modify existing components | |||
| - Integrate new plugins | |||
| ### 3. Advanced Customizations | |||
| - Restructure layouts | |||
| - Build custom applications | |||
| - Create new design systems | |||
| - Implement custom build processes | |||
| ## Customization Layers | |||
| ### SCSS Variables | |||
| The fastest way to customize Concept is through Sass variables: | |||
| ```scss | |||
| // src/scss/_variables.scss | |||
| $primary: #5969ff; | |||
| $secondary: #6c757d; | |||
| $success: #28a745; | |||
| $font-family-base: 'Inter', sans-serif; | |||
| $border-radius: 0.375rem; | |||
| ``` | |||
| ### Component Overrides | |||
| Override specific components without modifying core files: | |||
| ```scss | |||
| // src/scss/custom/_buttons.scss | |||
| .btn-primary { | |||
| background: linear-gradient(45deg, $primary, lighten($primary, 10%)); | |||
| border: none; | |||
| box-shadow: 0 4px 6px rgba($primary, 0.3); | |||
| } | |||
| ``` | |||
| ### Layout Modifications | |||
| Customize the overall layout structure: | |||
| ```javascript | |||
| // src/config/layout.js | |||
| export const layoutConfig = { | |||
| sidebar: { | |||
| width: '260px', | |||
| collapsed: '70px', | |||
| dark: true | |||
| }, | |||
| header: { | |||
| height: '70px', | |||
| fixed: true | |||
| } | |||
| }; | |||
| ``` | |||
| ## Key Customization Files | |||
| ### Style Customization | |||
| - **`_variables.scss`** - Global Sass variables | |||
| - **`main.scss`** - Main stylesheet entry | |||
| - **`custom/`** - Your custom styles directory | |||
| ### JavaScript Customization | |||
| - **`config/`** - Configuration files | |||
| - **`js/custom/`** - Custom JavaScript modules | |||
| - **`app.js`** - Main application logic | |||
| ### Layout Customization | |||
| - **`partials/layouts/`** - Layout templates | |||
| - **`partials/components/`** - Reusable components | |||
| - **`pages/`** - Page templates | |||
| ## Customization Workflow | |||
| ### Step 1: Plan Your Changes | |||
| Before starting, identify: | |||
| - What needs to be changed | |||
| - Which files are affected | |||
| - Whether to override or modify | |||
| - Impact on other components | |||
| ### Step 2: Set Up Custom Files | |||
| Create a custom directory structure: | |||
| ``` | |||
| src/ | |||
| ├── scss/ | |||
| │ └── custom/ | |||
| │ ├── _variables.scss # Your variables | |||
| │ ├── _components.scss # Component overrides | |||
| │ └── _theme.scss # Theme customizations | |||
| └── js/ | |||
| └── custom/ | |||
| ├── theme.js # Theme switcher | |||
| └── components.js # Custom components | |||
| ``` | |||
| ### Step 3: Override Safely | |||
| Always override rather than modify core files: | |||
| ```scss | |||
| // DO: Create custom/_buttons.scss | |||
| .btn-primary { | |||
| // Your customizations | |||
| } | |||
| // DON'T: Modify components/_buttons.scss directly | |||
| ``` | |||
| ### Step 4: Test Thoroughly | |||
| - Test in development mode | |||
| - Build for production | |||
| - Check responsive behavior | |||
| - Verify cross-browser compatibility | |||
| ## Quick Start Examples | |||
| ### Change Primary Color | |||
| ```scss | |||
| // src/scss/_variables.scss | |||
| $primary: #7c3aed; // Purple instead of blue | |||
| ``` | |||
| ### Change Font Family | |||
| ```scss | |||
| // src/scss/_variables.scss | |||
| $font-family-base: 'Roboto', sans-serif; | |||
| // Add font import | |||
| @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap'); | |||
| ``` | |||
| ### Customize Sidebar Width | |||
| ```scss | |||
| // src/scss/custom/_layout.scss | |||
| .sidebar { | |||
| width: 280px; // Instead of 260px | |||
| &.collapsed { | |||
| width: 80px; // Instead of 70px | |||
| } | |||
| } | |||
| ``` | |||
| ### Add Dark Mode | |||
| ```javascript | |||
| // src/js/custom/theme.js | |||
| export function initThemeSwitcher() { | |||
| const toggle = document.getElementById('darkModeToggle'); | |||
| toggle?.addEventListener('click', () => { | |||
| document.body.classList.toggle('dark-mode'); | |||
| localStorage.setItem('theme', | |||
| document.body.classList.contains('dark-mode') ? 'dark' : 'light' | |||
| ); | |||
| }); | |||
| } | |||
| ``` | |||
| ## Customization Best Practices | |||
| ### DO: | |||
| - ✅ Use variables for consistency | |||
| - ✅ Create custom files for overrides | |||
| - ✅ Document your customizations | |||
| - ✅ Test across browsers | |||
| - ✅ Keep customizations modular | |||
| - ✅ Use version control | |||
| ### DON'T: | |||
| - ❌ Modify core Bootstrap files | |||
| - ❌ Edit vendor libraries directly | |||
| - ❌ Use !important excessively | |||
| - ❌ Hardcode values | |||
| - ❌ Skip responsive testing | |||
| - ❌ Forget about accessibility | |||
| ## Common Customizations | |||
| ### 1. Branding | |||
| - Logo replacement | |||
| - Color scheme | |||
| - Typography | |||
| - Favicon | |||
| ### 2. Layout | |||
| - Sidebar behavior | |||
| - Header style | |||
| - Footer content | |||
| - Page width | |||
| ### 3. Components | |||
| - Button styles | |||
| - Card designs | |||
| - Form elements | |||
| - Table layouts | |||
| ### 4. Features | |||
| - Remove unused pages | |||
| - Add new functionality | |||
| - Integrate APIs | |||
| - Custom widgets | |||
| ## Advanced Customization | |||
| ### Creating a Theme System | |||
| ```javascript | |||
| // src/js/custom/theme-manager.js | |||
| class ThemeManager { | |||
| constructor() { | |||
| this.themes = { | |||
| default: { primary: '#5969ff', secondary: '#6c757d' }, | |||
| dark: { primary: '#1a1a1a', secondary: '#2d2d2d' }, | |||
| corporate: { primary: '#003366', secondary: '#0066cc' } | |||
| }; | |||
| } | |||
| applyTheme(themeName) { | |||
| const theme = this.themes[themeName]; | |||
| Object.entries(theme).forEach(([key, value]) => { | |||
| document.documentElement.style.setProperty(`--${key}`, value); | |||
| }); | |||
| } | |||
| } | |||
| ``` | |||
| ### Custom Build Process | |||
| ```javascript | |||
| // vite.config.custom.js | |||
| import { defineConfig } from 'vite'; | |||
| import customPlugin from './plugins/custom'; | |||
| export default defineConfig({ | |||
| plugins: [ | |||
| customPlugin({ | |||
| // Your custom options | |||
| }) | |||
| ] | |||
| }); | |||
| ``` | |||
| ## Troubleshooting Customizations | |||
| ### Styles Not Applying | |||
| 1. Check import order in `main.scss` | |||
| 2. Verify file paths | |||
| 3. Clear browser cache | |||
| 4. Check CSS specificity | |||
| ### JavaScript Errors | |||
| 1. Check console for errors | |||
| 2. Verify module imports | |||
| 3. Ensure DOM is ready | |||
| 4. Check for conflicts | |||
| ### Build Issues | |||
| 1. Clear Vite cache | |||
| 2. Check for syntax errors | |||
| 3. Verify dependencies | |||
| 4. Review build logs | |||
| ## Next Steps | |||
| Dive deeper into specific customization topics: | |||
| 1. **[Theming Guide](theming.md)** - Create custom themes | |||
| 2. **[Sass Variables](sass-variables.md)** - All available variables | |||
| 3. **[Color System](colors.md)** - Color customization | |||
| 4. **[Component Styling](components.md)** - Customize components | |||
| 5. **[Layout Options](../layout/overview.md)** - Layout customization | |||
| --- | |||
| Remember: Good customization maintains the template's quality while adding your unique touch. Start small, test often, and build incrementally! 🎨 | |||
| @ -0,0 +1,680 @@ | |||
| # Sass Variables Reference | |||
| This comprehensive guide documents all Sass variables available in Concept. These variables control every aspect of the template's appearance and behavior. | |||
| ## Variable Organization | |||
| Variables are organized into logical groups: | |||
| ```scss | |||
| src/scss/ | |||
| ├── _variables.scss # Main variables file | |||
| ├── bootstrap/ | |||
| │ └── _variables.scss # Bootstrap overrides | |||
| ├── custom/ | |||
| │ ├── _colors.scss # Color definitions | |||
| │ ├── _typography.scss # Font settings | |||
| │ ├── _spacing.scss # Spacing system | |||
| │ └── _components.scss # Component variables | |||
| └── themes/ | |||
| └── _theme-variables.scss # Theme-specific vars | |||
| ``` | |||
| ## Color Variables | |||
| ### Primary Colors | |||
| ```scss | |||
| // Brand colors | |||
| $primary: #5969ff !default; | |||
| $secondary: #6c757d !default; | |||
| $success: #28a745 !default; | |||
| $info: #17a2b8 !default; | |||
| $warning: #ffc107 !default; | |||
| $danger: #dc3545 !default; | |||
| $light: #f8f9fa !default; | |||
| $dark: #343a40 !default; | |||
| // Extended palette | |||
| $indigo: #6610f2 !default; | |||
| $purple: #6f42c1 !default; | |||
| $pink: #e83e8c !default; | |||
| $red: #dc3545 !default; | |||
| $orange: #fd7e14 !default; | |||
| $yellow: #ffc107 !default; | |||
| $green: #28a745 !default; | |||
| $teal: #20c997 !default; | |||
| $cyan: #17a2b8 !default; | |||
| ``` | |||
| ### Grayscale | |||
| ```scss | |||
| // Gray scale | |||
| $white: #ffffff !default; | |||
| $gray-100: #f8f9fa !default; | |||
| $gray-200: #e9ecef !default; | |||
| $gray-300: #dee2e6 !default; | |||
| $gray-400: #ced4da !default; | |||
| $gray-500: #adb5bd !default; | |||
| $gray-600: #6c757d !default; | |||
| $gray-700: #495057 !default; | |||
| $gray-800: #343a40 !default; | |||
| $gray-900: #212529 !default; | |||
| $black: #000000 !default; | |||
| // Semantic grays | |||
| $gray-light: $gray-100 !default; | |||
| $gray: $gray-600 !default; | |||
| $gray-dark: $gray-800 !default; | |||
| ``` | |||
| ### Theme Colors Map | |||
| ```scss | |||
| // Theme colors for generating utilities | |||
| $theme-colors: ( | |||
| "primary": $primary, | |||
| "secondary": $secondary, | |||
| "success": $success, | |||
| "info": $info, | |||
| "warning": $warning, | |||
| "danger": $danger, | |||
| "light": $light, | |||
| "dark": $dark, | |||
| "white": $white, | |||
| "gray": $gray-600, | |||
| "gray-dark": $gray-800 | |||
| ) !default; | |||
| // Additional colors | |||
| $extra-colors: ( | |||
| "indigo": $indigo, | |||
| "purple": $purple, | |||
| "pink": $pink, | |||
| "orange": $orange, | |||
| "teal": $teal, | |||
| "cyan": $cyan | |||
| ) !default; | |||
| ``` | |||
| ## Typography Variables | |||
| ### Font Families | |||
| ```scss | |||
| // System font stack | |||
| $font-family-sans-serif: | |||
| -apple-system, | |||
| BlinkMacSystemFont, | |||
| "Segoe UI", | |||
| Roboto, | |||
| "Helvetica Neue", | |||
| Arial, | |||
| sans-serif !default; | |||
| // Custom fonts | |||
| $font-family-base: 'Inter', $font-family-sans-serif !default; | |||
| $font-family-headings: 'Poppins', $font-family-sans-serif !default; | |||
| $font-family-monospace: | |||
| 'SFMono-Regular', | |||
| Menlo, | |||
| Monaco, | |||
| Consolas, | |||
| "Liberation Mono", | |||
| "Courier New", | |||
| monospace !default; | |||
| // Font assignments | |||
| $headings-font-family: $font-family-headings !default; | |||
| $display-font-family: $font-family-headings !default; | |||
| ``` | |||
| ### Font Sizes | |||
| ```scss | |||
| // Base size | |||
| $font-size-base: 1rem !default; // 16px | |||
| $font-size-root: 16px !default; | |||
| // Size scale | |||
| $font-size-xs: $font-size-base * 0.75 !default; // 12px | |||
| $font-size-sm: $font-size-base * 0.875 !default; // 14px | |||
| $font-size-lg: $font-size-base * 1.125 !default; // 18px | |||
| $font-size-xl: $font-size-base * 1.25 !default; // 20px | |||
| // Heading sizes | |||
| $h1-font-size: $font-size-base * 2.5 !default; // 40px | |||
| $h2-font-size: $font-size-base * 2 !default; // 32px | |||
| $h3-font-size: $font-size-base * 1.75 !default; // 28px | |||
| $h4-font-size: $font-size-base * 1.5 !default; // 24px | |||
| $h5-font-size: $font-size-base * 1.25 !default; // 20px | |||
| $h6-font-size: $font-size-base !default; // 16px | |||
| // Display sizes | |||
| $display1-size: 6rem !default; | |||
| $display2-size: 5.5rem !default; | |||
| $display3-size: 4.5rem !default; | |||
| $display4-size: 3.5rem !default; | |||
| ``` | |||
| ### Font Weights | |||
| ```scss | |||
| // Weight scale | |||
| $font-weight-lighter: lighter !default; | |||
| $font-weight-light: 300 !default; | |||
| $font-weight-normal: 400 !default; | |||
| $font-weight-medium: 500 !default; | |||
| $font-weight-semibold: 600 !default; | |||
| $font-weight-bold: 700 !default; | |||
| $font-weight-bolder: bolder !default; | |||
| // Component weights | |||
| $font-weight-base: $font-weight-normal !default; | |||
| $headings-font-weight: $font-weight-semibold !default; | |||
| $lead-font-weight: $font-weight-light !default; | |||
| $small-font-weight: $font-weight-normal !default; | |||
| ``` | |||
| ### Line Heights | |||
| ```scss | |||
| // Line height scale | |||
| $line-height-base: 1.5 !default; | |||
| $line-height-sm: 1.25 !default; | |||
| $line-height-lg: 2 !default; | |||
| // Heading line heights | |||
| $headings-line-height: 1.2 !default; | |||
| $display-line-height: 1.2 !default; | |||
| ``` | |||
| ## Spacing Variables | |||
| ### Spacer System | |||
| ```scss | |||
| // Base spacer | |||
| $spacer: 1rem !default; | |||
| // Spacer scale | |||
| $spacers: ( | |||
| 0: 0, | |||
| 1: $spacer * 0.25, // 4px | |||
| 2: $spacer * 0.5, // 8px | |||
| 3: $spacer, // 16px | |||
| 4: $spacer * 1.5, // 24px | |||
| 5: $spacer * 3, // 48px | |||
| 6: $spacer * 4, // 64px | |||
| 7: $spacer * 5, // 80px | |||
| 8: $spacer * 6 // 96px | |||
| ) !default; | |||
| // Component spacing | |||
| $paragraph-margin-bottom: 1rem !default; | |||
| $headings-margin-bottom: $spacer * 0.5 !default; | |||
| $label-margin-bottom: 0.5rem !default; | |||
| ``` | |||
| ### Grid Variables | |||
| ```scss | |||
| // Grid breakpoints | |||
| $grid-breakpoints: ( | |||
| xs: 0, | |||
| sm: 576px, | |||
| md: 768px, | |||
| lg: 992px, | |||
| xl: 1200px, | |||
| xxl: 1400px | |||
| ) !default; | |||
| // Container widths | |||
| $container-max-widths: ( | |||
| sm: 540px, | |||
| md: 720px, | |||
| lg: 960px, | |||
| xl: 1140px, | |||
| xxl: 1320px | |||
| ) !default; | |||
| // Grid settings | |||
| $grid-columns: 12 !default; | |||
| $grid-gutter-width: 1.5rem !default; | |||
| $grid-row-columns: 6 !default; | |||
| ``` | |||
| ## Component Variables | |||
| ### Borders | |||
| ```scss | |||
| // Border widths | |||
| $border-width: 1px !default; | |||
| $border-widths: ( | |||
| 0: 0, | |||
| 1: 1px, | |||
| 2: 2px, | |||
| 3: 3px, | |||
| 4: 4px, | |||
| 5: 5px | |||
| ) !default; | |||
| // Border colors | |||
| $border-color: $gray-300 !default; | |||
| $border-color-translucent: rgba($black, .175) !default; | |||
| // Border radius | |||
| $border-radius: 0.375rem !default; | |||
| $border-radius-sm: 0.25rem !default; | |||
| $border-radius-lg: 0.5rem !default; | |||
| $border-radius-xl: 1rem !default; | |||
| $border-radius-pill: 50rem !default; | |||
| ``` | |||
| ### Shadows | |||
| ```scss | |||
| // Box shadows | |||
| $box-shadow: 0 0.125rem 0.25rem rgba($black, 0.075) !default; | |||
| $box-shadow-sm: 0 0.0625rem 0.125rem rgba($black, 0.075) !default; | |||
| $box-shadow-lg: 0 0.5rem 1rem rgba($black, 0.15) !default; | |||
| $box-shadow-xl: 0 1rem 3rem rgba($black, 0.175) !default; | |||
| $box-shadow-inset: inset 0 1px 2px rgba($black, 0.075) !default; | |||
| // Text shadows | |||
| $text-shadow: 0 0.0625rem 0.125rem rgba($black, 0.075) !default; | |||
| ``` | |||
| ### Z-index | |||
| ```scss | |||
| // Z-index scale | |||
| $zindex-dropdown: 1000 !default; | |||
| $zindex-sticky: 1020 !default; | |||
| $zindex-fixed: 1030 !default; | |||
| $zindex-modal-backdrop: 1040 !default; | |||
| $zindex-offcanvas: 1050 !default; | |||
| $zindex-modal: 1060 !default; | |||
| $zindex-popover: 1070 !default; | |||
| $zindex-tooltip: 1080 !default; | |||
| $zindex-toast: 1090 !default; | |||
| ``` | |||
| ## Layout Variables | |||
| ### Sidebar | |||
| ```scss | |||
| // Sidebar dimensions | |||
| $sidebar-width: 260px !default; | |||
| $sidebar-collapsed-width: 70px !default; | |||
| $sidebar-mini-width: 200px !default; | |||
| // Sidebar colors | |||
| $sidebar-bg: $white !default; | |||
| $sidebar-dark-bg: $gray-900 !default; | |||
| $sidebar-border-color: $border-color !default; | |||
| // Sidebar typography | |||
| $sidebar-link-color: $gray-700 !default; | |||
| $sidebar-link-hover: $primary !default; | |||
| $sidebar-link-active: $primary !default; | |||
| $sidebar-text-color: $gray-600 !default; | |||
| // Sidebar spacing | |||
| $sidebar-padding-x: 1rem !default; | |||
| $sidebar-padding-y: 1.5rem !default; | |||
| $sidebar-item-padding: 0.625rem 1rem !default; | |||
| ``` | |||
| ### Header | |||
| ```scss | |||
| // Header dimensions | |||
| $header-height: 70px !default; | |||
| $header-padding-y: 1rem !default; | |||
| $header-padding-x: 1.5rem !default; | |||
| // Header colors | |||
| $header-bg: $white !default; | |||
| $header-border-color: $border-color !default; | |||
| $header-link-color: $gray-700 !default; | |||
| $header-link-hover: $primary !default; | |||
| // Header shadow | |||
| $header-box-shadow: $box-shadow-sm !default; | |||
| ``` | |||
| ### Footer | |||
| ```scss | |||
| // Footer settings | |||
| $footer-height: 60px !default; | |||
| $footer-padding-y: 1rem !default; | |||
| $footer-padding-x: 1.5rem !default; | |||
| $footer-bg: $gray-100 !default; | |||
| $footer-color: $gray-600 !default; | |||
| $footer-border-color: $border-color !default; | |||
| ``` | |||
| ## Form Variables | |||
| ### Input Settings | |||
| ```scss | |||
| // Input dimensions | |||
| $input-height: 2.75rem !default; | |||
| $input-height-sm: 2.125rem !default; | |||
| $input-height-lg: 3.375rem !default; | |||
| $input-line-height: $line-height-base !default; | |||
| // Input padding | |||
| $input-padding-y: 0.5rem !default; | |||
| $input-padding-x: 0.75rem !default; | |||
| $input-padding-y-sm: 0.25rem !default; | |||
| $input-padding-x-sm: 0.5rem !default; | |||
| $input-padding-y-lg: 0.75rem !default; | |||
| $input-padding-x-lg: 1rem !default; | |||
| // Input appearance | |||
| $input-font-family: $font-family-base !default; | |||
| $input-font-size: $font-size-base !default; | |||
| $input-font-weight: $font-weight-base !default; | |||
| $input-bg: $white !default; | |||
| $input-disabled-bg: $gray-200 !default; | |||
| $input-disabled-color: $gray-600 !default; | |||
| // Input borders | |||
| $input-border-width: $border-width !default; | |||
| $input-border-color: $gray-400 !default; | |||
| $input-border-radius: $border-radius !default; | |||
| // Input states | |||
| $input-focus-bg: $input-bg !default; | |||
| $input-focus-color: $input-color !default; | |||
| $input-focus-border-color: lighten($primary, 25%) !default; | |||
| $input-focus-box-shadow: 0 0 0 0.2rem rgba($primary, 0.25) !default; | |||
| ``` | |||
| ### Form Validation | |||
| ```scss | |||
| // Validation colors | |||
| $form-valid-color: $success !default; | |||
| $form-valid-border-color: $success !default; | |||
| $form-invalid-color: $danger !default; | |||
| $form-invalid-border-color: $danger !default; | |||
| // Feedback styling | |||
| $form-feedback-font-size: $font-size-sm !default; | |||
| $form-feedback-valid-color: $form-valid-color !default; | |||
| $form-feedback-invalid-color: $form-invalid-color !default; | |||
| $form-feedback-icon-valid: url("data:image/svg+xml,<svg>...</svg>") !default; | |||
| $form-feedback-icon-invalid: url("data:image/svg+xml,<svg>...</svg>") !default; | |||
| ``` | |||
| ## Button Variables | |||
| ### Button Base | |||
| ```scss | |||
| // Button padding | |||
| $btn-padding-y: 0.5rem !default; | |||
| $btn-padding-x: 1rem !default; | |||
| $btn-padding-y-sm: 0.25rem !default; | |||
| $btn-padding-x-sm: 0.5rem !default; | |||
| $btn-padding-y-lg: 0.75rem !default; | |||
| $btn-padding-x-lg: 1.5rem !default; | |||
| // Button typography | |||
| $btn-font-family: $font-family-base !default; | |||
| $btn-font-size: $font-size-base !default; | |||
| $btn-font-size-sm: $font-size-sm !default; | |||
| $btn-font-size-lg: $font-size-lg !default; | |||
| $btn-font-weight: $font-weight-normal !default; | |||
| $btn-line-height: $line-height-base !default; | |||
| // Button appearance | |||
| $btn-border-width: $border-width !default; | |||
| $btn-border-radius: $border-radius !default; | |||
| $btn-border-radius-sm: $border-radius-sm !default; | |||
| $btn-border-radius-lg: $border-radius-lg !default; | |||
| $btn-box-shadow: $box-shadow-sm !default; | |||
| $btn-focus-box-shadow: 0 0 0 0.2rem !default; | |||
| // Button states | |||
| $btn-disabled-opacity: 0.65 !default; | |||
| $btn-transition: color 0.15s ease-in-out, | |||
| background-color 0.15s ease-in-out, | |||
| border-color 0.15s ease-in-out, | |||
| box-shadow 0.15s ease-in-out !default; | |||
| ``` | |||
| ## Card Variables | |||
| ```scss | |||
| // Card structure | |||
| $card-spacer-y: 1.25rem !default; | |||
| $card-spacer-x: 1.25rem !default; | |||
| $card-padding-y: 0 !default; | |||
| $card-padding-x: 0 !default; | |||
| $card-bg: $white !default; | |||
| $card-border-width: $border-width !default; | |||
| $card-border-color: rgba($black, 0.125) !default; | |||
| $card-border-radius: $border-radius !default; | |||
| $card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default; | |||
| // Card variations | |||
| $card-cap-padding-y: 0.75rem !default; | |||
| $card-cap-padding-x: 1.25rem !default; | |||
| $card-cap-bg: rgba($black, 0.03) !default; | |||
| $card-cap-color: null !default; | |||
| $card-height: null !default; | |||
| $card-color: null !default; | |||
| $card-bg: $white !default; | |||
| $card-img-overlay-padding: 1.25rem !default; | |||
| $card-box-shadow: $box-shadow !default; | |||
| ``` | |||
| ## Table Variables | |||
| ```scss | |||
| // Table structure | |||
| $table-cell-padding-y: 0.75rem !default; | |||
| $table-cell-padding-x: 0.75rem !default; | |||
| $table-cell-padding-y-sm: 0.3rem !default; | |||
| $table-cell-padding-x-sm: 0.3rem !default; | |||
| // Table colors | |||
| $table-bg: transparent !default; | |||
| $table-accent-bg: rgba($black, 0.02) !default; | |||
| $table-hover-bg: rgba($black, 0.03) !default; | |||
| $table-active-bg: rgba($black, 0.04) !default; | |||
| $table-border-color: $border-color !default; | |||
| // Table variants | |||
| $table-dark-bg: $gray-900 !default; | |||
| $table-dark-accent-bg: rgba($white, 0.05) !default; | |||
| $table-dark-hover-bg: rgba($white, 0.075) !default; | |||
| $table-dark-border-color: lighten($gray-900, 5%) !default; | |||
| $table-dark-color: $white !default; | |||
| // Striped tables | |||
| $table-striped-bg-factor: 0.02 !default; | |||
| $table-striped-bg: rgba($black, $table-striped-bg-factor) !default; | |||
| $table-striped-order: odd !default; | |||
| // Table state colors | |||
| $table-bg-scale: -80% !default; | |||
| ``` | |||
| ## Animation Variables | |||
| ```scss | |||
| // Transitions | |||
| $transition-base: all 0.2s ease-in-out !default; | |||
| $transition-fade: opacity 0.15s linear !default; | |||
| $transition-collapse: height 0.35s ease !default; | |||
| $transition-collapse-width: width 0.35s ease !default; | |||
| // Animation durations | |||
| $animation-duration-base: 1s !default; | |||
| $animation-duration-fast: 0.5s !default; | |||
| $animation-duration-slow: 2s !default; | |||
| // Easing functions | |||
| $ease-in-out: cubic-bezier(0.4, 0, 0.2, 1) !default; | |||
| $ease-out: cubic-bezier(0.0, 0, 0.2, 1) !default; | |||
| $ease-in: cubic-bezier(0.4, 0, 1, 1) !default; | |||
| $ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55) !default; | |||
| ``` | |||
| ## Utility Variables | |||
| ### Spacing Utilities | |||
| ```scss | |||
| // Enable responsive utilities | |||
| $enable-responsive-spacing: true !default; | |||
| // Negative margin utilities | |||
| $enable-negative-margins: true !default; | |||
| // Print utilities | |||
| $enable-print-styles: true !default; | |||
| ``` | |||
| ### Color Utilities | |||
| ```scss | |||
| // Color contrast settings | |||
| $min-contrast-ratio: 4.5 !default; | |||
| $color-contrast-dark: $black !default; | |||
| $color-contrast-light: $white !default; | |||
| // Link colors | |||
| $link-color: $primary !default; | |||
| $link-decoration: underline !default; | |||
| $link-shade-percentage: 20% !default; | |||
| $link-hover-color: shift-color($link-color, $link-shade-percentage) !default; | |||
| $link-hover-decoration: null !default; | |||
| ``` | |||
| ## Using Variables | |||
| ### Basic Usage | |||
| ```scss | |||
| // In your custom styles | |||
| .custom-component { | |||
| padding: $spacer; | |||
| border-radius: $border-radius; | |||
| background-color: $primary; | |||
| color: $white; | |||
| } | |||
| ``` | |||
| ### With Sass Functions | |||
| ```scss | |||
| // Using color functions | |||
| .custom-button { | |||
| background-color: $primary; | |||
| &:hover { | |||
| background-color: darken($primary, 10%); | |||
| } | |||
| &:active { | |||
| background-color: darken($primary, 15%); | |||
| } | |||
| } | |||
| // Using spacing functions | |||
| .custom-spacing { | |||
| margin: map-get($spacers, 3); | |||
| padding: calc(#{$spacer} * 2); | |||
| } | |||
| ``` | |||
| ### Creating Custom Variables | |||
| ```scss | |||
| // Define your own variables | |||
| $custom-header-height: 80px; | |||
| $custom-sidebar-width: 280px; | |||
| $custom-primary-gradient: linear-gradient(135deg, $primary 0%, darken($primary, 10%) 100%); | |||
| // Use them in your styles | |||
| .custom-layout { | |||
| --header-height: #{$custom-header-height}; | |||
| --sidebar-width: #{$custom-sidebar-width}; | |||
| .header { | |||
| height: var(--header-height); | |||
| } | |||
| .sidebar { | |||
| width: var(--sidebar-width); | |||
| } | |||
| } | |||
| ``` | |||
| ## Best Practices | |||
| ### Variable Naming | |||
| ```scss | |||
| // DO: Use descriptive, hierarchical names | |||
| $card-header-padding-y: 0.75rem; | |||
| $card-header-padding-x: 1rem; | |||
| $card-header-bg: $gray-100; | |||
| // DON'T: Use generic names | |||
| $padding: 0.75rem; | |||
| $bg: $gray-100; | |||
| ``` | |||
| ### Default Values | |||
| ```scss | |||
| // Always use !default for overrideable variables | |||
| $custom-primary: #007bff !default; | |||
| $custom-border-radius: 0.25rem !default; | |||
| // This allows users to override before importing | |||
| $custom-primary: #28a745; | |||
| @import "your-framework"; | |||
| ``` | |||
| ### Variable Scoping | |||
| ```scss | |||
| // Global variables at root | |||
| $global-font-size: 16px; | |||
| // Component-specific with prefix | |||
| $btn-padding-y: 0.5rem; | |||
| $btn-padding-x: 1rem; | |||
| // Local variables within mixins/functions | |||
| @mixin custom-mixin() { | |||
| $local-spacing: $spacer * 2; | |||
| padding: $local-spacing; | |||
| } | |||
| ``` | |||
| ## Next Steps | |||
| Learn more about customization: | |||
| 1. **[Color System](colors.md)** - Deep dive into color utilities | |||
| 2. **[Theming Guide](theming.md)** - Create custom themes | |||
| 3. **[Component Customization](components.md)** - Override components | |||
| 4. **[Custom Builds](../advanced/custom-builds.md)** - Optimize variables | |||
| --- | |||
| Master these variables to unlock the full customization potential of Concept! 🎨 | |||
| @ -0,0 +1,614 @@ | |||
| # Theming Guide | |||
| Concept is designed with theming in mind, allowing you to create custom themes that match your brand or project requirements. This guide covers everything from simple color changes to complete theme systems. | |||
| ## Theme Structure | |||
| ### Theme Layers | |||
| Concept's theming system works in layers: | |||
| 1. **Bootstrap Core** - Base Bootstrap 5 variables | |||
| 2. **Concept Defaults** - Template-specific customizations | |||
| 3. **Custom Theme** - Your theme overrides | |||
| 4. **Component Overrides** - Specific component tweaks | |||
| ### Key Theme Files | |||
| ``` | |||
| src/scss/ | |||
| ├── _variables.scss # Global variables | |||
| ├── themes/ | |||
| │ ├── _default.scss # Default theme | |||
| │ ├── _dark.scss # Dark theme | |||
| │ └── _custom.scss # Your custom theme | |||
| ├── main.scss # Import orchestration | |||
| └── custom/ | |||
| └── _theme-overrides.scss # Runtime overrides | |||
| ``` | |||
| ## Creating a Custom Theme | |||
| ### Step 1: Create Theme File | |||
| Create a new theme file: | |||
| ```scss | |||
| // src/scss/themes/_corporate.scss | |||
| // Theme name and metadata | |||
| $theme-name: "corporate"; | |||
| $theme-description: "Professional corporate theme"; | |||
| // Color palette | |||
| $theme-colors: ( | |||
| "primary": #003366, | |||
| "secondary": #0066cc, | |||
| "success": #00a86b, | |||
| "info": #17a2b8, | |||
| "warning": #ffc107, | |||
| "danger": #dc3545, | |||
| "light": #f8f9fa, | |||
| "dark": #001f3f | |||
| ); | |||
| // Extended colors | |||
| $theme-extended-colors: ( | |||
| "brand": #002244, | |||
| "accent": #0088ff, | |||
| "muted": #6c757d, | |||
| "highlight": #ffeb3b | |||
| ); | |||
| // Typography | |||
| $theme-fonts: ( | |||
| "base": "'Inter', -apple-system, BlinkMacSystemFont, sans-serif", | |||
| "heading": "'Poppins', sans-serif", | |||
| "mono": "'JetBrains Mono', monospace" | |||
| ); | |||
| // Spacing | |||
| $theme-spacing: ( | |||
| "tight": 0.25rem, | |||
| "normal": 1rem, | |||
| "relaxed": 1.5rem, | |||
| "loose": 2rem | |||
| ); | |||
| // Component specific | |||
| $theme-components: ( | |||
| "border-radius": 0.375rem, | |||
| "border-radius-sm": 0.25rem, | |||
| "border-radius-lg": 0.5rem, | |||
| "box-shadow": 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075), | |||
| "box-shadow-lg": 0 0.5rem 1rem rgba(0, 0, 0, 0.15) | |||
| ); | |||
| ``` | |||
| ### Step 2: Apply Theme Variables | |||
| Update your main variables file: | |||
| ```scss | |||
| // src/scss/_variables.scss | |||
| // Import theme | |||
| @import "themes/corporate"; | |||
| // Apply theme colors to Bootstrap | |||
| $primary: map-get($theme-colors, "primary"); | |||
| $secondary: map-get($theme-colors, "secondary"); | |||
| $success: map-get($theme-colors, "success"); | |||
| $info: map-get($theme-colors, "info"); | |||
| $warning: map-get($theme-colors, "warning"); | |||
| $danger: map-get($theme-colors, "danger"); | |||
| $light: map-get($theme-colors, "light"); | |||
| $dark: map-get($theme-colors, "dark"); | |||
| // Apply theme fonts | |||
| $font-family-base: map-get($theme-fonts, "base"); | |||
| $headings-font-family: map-get($theme-fonts, "heading"); | |||
| $font-family-monospace: map-get($theme-fonts, "mono"); | |||
| // Apply component settings | |||
| $border-radius: map-get($theme-components, "border-radius"); | |||
| $border-radius-sm: map-get($theme-components, "border-radius-sm"); | |||
| $border-radius-lg: map-get($theme-components, "border-radius-lg"); | |||
| $box-shadow: map-get($theme-components, "box-shadow"); | |||
| $box-shadow-lg: map-get($theme-components, "box-shadow-lg"); | |||
| ``` | |||
| ### Step 3: Create Theme Utilities | |||
| Add theme-specific utility classes: | |||
| ```scss | |||
| // src/scss/themes/_corporate-utilities.scss | |||
| // Extended color utilities | |||
| @each $name, $color in $theme-extended-colors { | |||
| .text-#{$name} { | |||
| color: $color !important; | |||
| } | |||
| .bg-#{$name} { | |||
| background-color: $color !important; | |||
| } | |||
| .border-#{$name} { | |||
| border-color: $color !important; | |||
| } | |||
| .btn-#{$name} { | |||
| @include button-variant($color, $color); | |||
| } | |||
| } | |||
| // Spacing utilities | |||
| @each $name, $space in $theme-spacing { | |||
| .spacing-#{$name} { | |||
| padding: $space; | |||
| margin: $space; | |||
| } | |||
| } | |||
| ``` | |||
| ## Dark Mode Implementation | |||
| ### CSS Variables Approach | |||
| ```scss | |||
| // src/scss/themes/_dark-mode.scss | |||
| :root { | |||
| // Light mode defaults | |||
| --bg-primary: #ffffff; | |||
| --bg-secondary: #f8f9fa; | |||
| --text-primary: #212529; | |||
| --text-secondary: #6c757d; | |||
| --border-color: #dee2e6; | |||
| --shadow-color: rgba(0, 0, 0, 0.1); | |||
| } | |||
| [data-theme="dark"] { | |||
| // Dark mode overrides | |||
| --bg-primary: #1a1a1a; | |||
| --bg-secondary: #2d2d2d; | |||
| --text-primary: #ffffff; | |||
| --text-secondary: #adb5bd; | |||
| --border-color: #495057; | |||
| --shadow-color: rgba(0, 0, 0, 0.3); | |||
| // Component overrides | |||
| --card-bg: var(--bg-secondary); | |||
| --sidebar-bg: #161616; | |||
| --header-bg: var(--bg-secondary); | |||
| } | |||
| // Apply variables | |||
| body { | |||
| background-color: var(--bg-primary); | |||
| color: var(--text-primary); | |||
| } | |||
| .card { | |||
| background-color: var(--card-bg); | |||
| border-color: var(--border-color); | |||
| } | |||
| ``` | |||
| ### JavaScript Theme Switcher | |||
| ```javascript | |||
| // src/js/theme-switcher.js | |||
| export class ThemeSwitcher { | |||
| constructor() { | |||
| this.theme = this.loadTheme() || 'light'; | |||
| this.init(); | |||
| } | |||
| init() { | |||
| // Apply saved theme | |||
| this.applyTheme(this.theme); | |||
| // Setup toggle button | |||
| const toggle = document.getElementById('theme-toggle'); | |||
| if (toggle) { | |||
| toggle.addEventListener('click', () => this.toggleTheme()); | |||
| } | |||
| // Watch for system preference changes | |||
| if (window.matchMedia) { | |||
| window.matchMedia('(prefers-color-scheme: dark)') | |||
| .addEventListener('change', e => { | |||
| if (this.theme === 'auto') { | |||
| this.applySystemTheme(); | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| toggleTheme() { | |||
| const themes = ['light', 'dark', 'auto']; | |||
| const currentIndex = themes.indexOf(this.theme); | |||
| this.theme = themes[(currentIndex + 1) % themes.length]; | |||
| this.applyTheme(this.theme); | |||
| this.saveTheme(this.theme); | |||
| } | |||
| applyTheme(theme) { | |||
| if (theme === 'auto') { | |||
| this.applySystemTheme(); | |||
| } else { | |||
| document.documentElement.setAttribute('data-theme', theme); | |||
| } | |||
| this.updateToggleButton(theme); | |||
| } | |||
| applySystemTheme() { | |||
| const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches; | |||
| document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light'); | |||
| } | |||
| updateToggleButton(theme) { | |||
| const toggle = document.getElementById('theme-toggle'); | |||
| if (toggle) { | |||
| const icon = toggle.querySelector('i'); | |||
| icon.className = theme === 'dark' ? 'fa-solid fa-sun' : | |||
| theme === 'auto' ? 'fa-solid fa-circle-half-stroke' : | |||
| 'fa-solid fa-moon'; | |||
| } | |||
| } | |||
| saveTheme(theme) { | |||
| localStorage.setItem('concept-theme', theme); | |||
| } | |||
| loadTheme() { | |||
| return localStorage.getItem('concept-theme'); | |||
| } | |||
| } | |||
| // Auto-initialize | |||
| new ThemeSwitcher(); | |||
| ``` | |||
| ## Theme Presets | |||
| ### Minimal Theme | |||
| ```scss | |||
| // src/scss/themes/_minimal.scss | |||
| $theme-colors: ( | |||
| "primary": #000000, | |||
| "secondary": #666666, | |||
| "success": #00c853, | |||
| "danger": #ff1744, | |||
| "light": #ffffff, | |||
| "dark": #000000 | |||
| ); | |||
| $theme-components: ( | |||
| "border-radius": 0, | |||
| "box-shadow": none, | |||
| "border-width": 1px | |||
| ); | |||
| // Minimal typography | |||
| $font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; | |||
| $headings-font-weight: 300; | |||
| $btn-font-weight: 400; | |||
| ``` | |||
| ### Material Design Theme | |||
| ```scss | |||
| // src/scss/themes/_material.scss | |||
| $theme-colors: ( | |||
| "primary": #1976d2, | |||
| "secondary": #dc004e, | |||
| "success": #388e3c, | |||
| "info": #0288d1, | |||
| "warning": #f57c00, | |||
| "danger": #d32f2f | |||
| ); | |||
| $theme-components: ( | |||
| "border-radius": 4px, | |||
| "box-shadow": 0 3px 1px -2px rgba(0,0,0,.2), | |||
| 0 2px 2px 0 rgba(0,0,0,.14), | |||
| 0 1px 5px 0 rgba(0,0,0,.12), | |||
| "transition": all 0.3s cubic-bezier(0.4, 0, 0.2, 1) | |||
| ); | |||
| // Material typography | |||
| $font-family-base: "Roboto", sans-serif; | |||
| $headings-font-weight: 400; | |||
| ``` | |||
| ### Gradient Theme | |||
| ```scss | |||
| // src/scss/themes/_gradient.scss | |||
| // Gradient backgrounds | |||
| $gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |||
| $gradient-success: linear-gradient(135deg, #00c853 0%, #00e676 100%); | |||
| $gradient-danger: linear-gradient(135deg, #ff5252 0%, #ff1744 100%); | |||
| // Apply to buttons | |||
| .btn-primary { | |||
| background: $gradient-primary; | |||
| border: none; | |||
| &:hover { | |||
| background: linear-gradient(135deg, #5a67d8 0%, #6b46a1 100%); | |||
| } | |||
| } | |||
| // Gradient cards | |||
| .card-gradient { | |||
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |||
| border: none; | |||
| } | |||
| // Gradient text | |||
| .text-gradient { | |||
| background: $gradient-primary; | |||
| -webkit-background-clip: text; | |||
| -webkit-text-fill-color: transparent; | |||
| background-clip: text; | |||
| } | |||
| ``` | |||
| ## Component Theming | |||
| ### Sidebar Theming | |||
| ```scss | |||
| // src/scss/components/_sidebar-theme.scss | |||
| .sidebar { | |||
| // Use theme variables | |||
| background-color: var(--sidebar-bg, $sidebar-bg); | |||
| color: var(--sidebar-color, $sidebar-color); | |||
| // Dark sidebar variant | |||
| &.sidebar-dark { | |||
| --sidebar-bg: #1e1e1e; | |||
| --sidebar-color: #ffffff; | |||
| --sidebar-link-color: rgba(255, 255, 255, 0.8); | |||
| --sidebar-link-hover: #ffffff; | |||
| --sidebar-border: rgba(255, 255, 255, 0.1); | |||
| } | |||
| // Light sidebar variant | |||
| &.sidebar-light { | |||
| --sidebar-bg: #ffffff; | |||
| --sidebar-color: #495057; | |||
| --sidebar-link-color: #495057; | |||
| --sidebar-link-hover: #000000; | |||
| --sidebar-border: rgba(0, 0, 0, 0.1); | |||
| } | |||
| // Gradient sidebar | |||
| &.sidebar-gradient { | |||
| background: linear-gradient(180deg, var(--gradient-start) 0%, var(--gradient-end) 100%); | |||
| } | |||
| } | |||
| ``` | |||
| ### Card Theming | |||
| ```scss | |||
| // src/scss/components/_card-theme.scss | |||
| .card { | |||
| // Theme variants | |||
| &.card-minimal { | |||
| border: none; | |||
| box-shadow: none; | |||
| background-color: transparent; | |||
| } | |||
| &.card-outlined { | |||
| background-color: transparent; | |||
| border-width: 2px; | |||
| } | |||
| &.card-elevated { | |||
| border: none; | |||
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); | |||
| &:hover { | |||
| transform: translateY(-5px); | |||
| box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15); | |||
| } | |||
| } | |||
| &.card-glassmorphic { | |||
| background: rgba(255, 255, 255, 0.1); | |||
| backdrop-filter: blur(10px); | |||
| border: 1px solid rgba(255, 255, 255, 0.2); | |||
| } | |||
| } | |||
| ``` | |||
| ## Theme Configuration | |||
| ### Theme Manager | |||
| ```javascript | |||
| // src/js/theme-manager.js | |||
| export class ThemeManager { | |||
| constructor() { | |||
| this.themes = { | |||
| default: () => import('./themes/default'), | |||
| dark: () => import('./themes/dark'), | |||
| corporate: () => import('./themes/corporate'), | |||
| minimal: () => import('./themes/minimal') | |||
| }; | |||
| this.currentTheme = 'default'; | |||
| this.init(); | |||
| } | |||
| async init() { | |||
| const savedTheme = localStorage.getItem('selected-theme') || 'default'; | |||
| await this.loadTheme(savedTheme); | |||
| } | |||
| async loadTheme(themeName) { | |||
| if (!this.themes[themeName]) { | |||
| console.error(`Theme "${themeName}" not found`); | |||
| return; | |||
| } | |||
| try { | |||
| // Remove previous theme | |||
| this.removeTheme(this.currentTheme); | |||
| // Load new theme | |||
| const theme = await this.themes[themeName](); | |||
| theme.apply(); | |||
| this.currentTheme = themeName; | |||
| localStorage.setItem('selected-theme', themeName); | |||
| // Emit theme change event | |||
| window.dispatchEvent(new CustomEvent('theme-changed', { | |||
| detail: { theme: themeName } | |||
| })); | |||
| } catch (error) { | |||
| console.error('Failed to load theme:', error); | |||
| } | |||
| } | |||
| removeTheme(themeName) { | |||
| document.documentElement.classList.remove(`theme-${themeName}`); | |||
| } | |||
| getAvailableThemes() { | |||
| return Object.keys(this.themes); | |||
| } | |||
| getCurrentTheme() { | |||
| return this.currentTheme; | |||
| } | |||
| } | |||
| ``` | |||
| ### Theme Settings UI | |||
| ```html | |||
| <!-- Theme selection dropdown --> | |||
| <div class="theme-selector"> | |||
| <label for="theme-select">Choose Theme:</label> | |||
| <select id="theme-select" class="form-select"> | |||
| <option value="default">Default</option> | |||
| <option value="dark">Dark</option> | |||
| <option value="corporate">Corporate</option> | |||
| <option value="minimal">Minimal</option> | |||
| </select> | |||
| </div> | |||
| <!-- Theme customizer panel --> | |||
| <div class="theme-customizer"> | |||
| <h5>Customize Theme</h5> | |||
| <!-- Color pickers --> | |||
| <div class="color-picker-group"> | |||
| <label>Primary Color</label> | |||
| <input type="color" id="primary-color" value="#5969ff"> | |||
| </div> | |||
| <!-- Font selection --> | |||
| <div class="font-selector"> | |||
| <label>Font Family</label> | |||
| <select id="font-family"> | |||
| <option value="Inter">Inter</option> | |||
| <option value="Roboto">Roboto</option> | |||
| <option value="Poppins">Poppins</option> | |||
| </select> | |||
| </div> | |||
| <!-- Border radius --> | |||
| <div class="radius-slider"> | |||
| <label>Border Radius</label> | |||
| <input type="range" id="border-radius" min="0" max="20" value="8"> | |||
| </div> | |||
| </div> | |||
| ``` | |||
| ## Best Practices | |||
| ### DO: | |||
| - ✅ Use CSS variables for dynamic theming | |||
| - ✅ Keep themes modular and importable | |||
| - ✅ Test themes across all components | |||
| - ✅ Provide theme preview functionality | |||
| - ✅ Save user theme preference | |||
| - ✅ Consider accessibility (contrast ratios) | |||
| ### DON'T: | |||
| - ❌ Hardcode colors in components | |||
| - ❌ Use !important excessively | |||
| - ❌ Create themes without testing | |||
| - ❌ Ignore system preferences | |||
| - ❌ Mix theme systems | |||
| - ❌ Forget about print styles | |||
| ## Performance Optimization | |||
| ### Lazy Load Themes | |||
| ```javascript | |||
| // Only load theme CSS when needed | |||
| async function loadThemeCSS(themeName) { | |||
| const link = document.createElement('link'); | |||
| link.rel = 'stylesheet'; | |||
| link.href = `/themes/${themeName}.css`; | |||
| link.id = `theme-${themeName}`; | |||
| document.head.appendChild(link); | |||
| // Wait for load | |||
| return new Promise((resolve) => { | |||
| link.onload = resolve; | |||
| }); | |||
| } | |||
| ``` | |||
| ### Theme Preloading | |||
| ```html | |||
| <!-- Preload critical theme resources --> | |||
| <link rel="preload" href="/themes/default.css" as="style"> | |||
| <link rel="preload" href="/fonts/inter.woff2" as="font" crossorigin> | |||
| ``` | |||
| ## Troubleshooting | |||
| ### Common Issues | |||
| 1. **Theme not applying**: Check import order in main.scss | |||
| 2. **Colors not updating**: Clear browser cache, check CSS specificity | |||
| 3. **Dark mode flashing**: Add theme class to HTML element early | |||
| 4. **Font loading issues**: Use font-display: swap | |||
| 5. **Performance issues**: Minimize theme CSS, use CSS variables | |||
| ## Next Steps | |||
| Explore more customization options: | |||
| 1. **[Sass Variables](sass-variables.md)** - All available variables | |||
| 2. **[Color System](colors.md)** - Color utilities and palette | |||
| 3. **[Component Styling](components.md)** - Component customization | |||
| 4. **[Layout Theming](../layout/theming.md)** - Layout-specific theming | |||
| --- | |||
| With proper theming, you can transform Concept to match any brand or design system. Start with colors and typography, then expand to complete theme systems! 🎨 | |||
| @ -0,0 +1,427 @@ | |||
| # Build Tools & Configuration | |||
| Concept uses Vite as its build tool, providing lightning-fast development and optimized production builds. This guide covers everything you need to know about the build system. | |||
| ## Why Vite? | |||
| Vite offers several advantages over traditional bundlers: | |||
| - ⚡ **Instant Server Start** - No bundling required in development | |||
| - 🔥 **Lightning Fast HMR** - Hot Module Replacement in milliseconds | |||
| - 📦 **Optimized Builds** - Rollup-based production builds | |||
| - 🎯 **Native ESM** - Leverages browser's native ES modules | |||
| - 🔧 **Zero Config** - Works out of the box with sensible defaults | |||
| ## Vite Configuration | |||
| The `vite.config.js` file controls how Vite builds your project: | |||
| ```javascript | |||
| import { defineConfig } from 'vite'; | |||
| import { resolve } from 'path'; | |||
| import handlebars from 'vite-plugin-handlebars'; | |||
| import { viteStaticCopy } from 'vite-plugin-static-copy'; | |||
| export default defineConfig({ | |||
| root: 'src', | |||
| base: '/', | |||
| build: { | |||
| outDir: '../dist', | |||
| emptyOutDir: true, | |||
| rollupOptions: { | |||
| input: { | |||
| main: resolve(__dirname, 'src/index.html'), | |||
| // Add all your pages here | |||
| login: resolve(__dirname, 'src/pages/auth/login.html'), | |||
| products: resolve(__dirname, 'src/pages/ecommerce/products.html'), | |||
| // ... more pages | |||
| } | |||
| } | |||
| }, | |||
| plugins: [ | |||
| handlebars({ | |||
| partialDirectory: resolve(__dirname, 'src/partials'), | |||
| context: { | |||
| title: 'Concept Dashboard' | |||
| } | |||
| }), | |||
| viteStaticCopy({ | |||
| targets: [ | |||
| { src: 'assets/images/*', dest: 'assets/images' } | |||
| ] | |||
| }) | |||
| ], | |||
| server: { | |||
| port: 3000, | |||
| hot: true, | |||
| open: true | |||
| } | |||
| }); | |||
| ``` | |||
| ## Key Configuration Options | |||
| ### Root Directory | |||
| ```javascript | |||
| root: 'src' | |||
| ``` | |||
| Sets the project root to the `src` directory. | |||
| ### Build Output | |||
| ```javascript | |||
| build: { | |||
| outDir: '../dist', | |||
| emptyOutDir: true | |||
| } | |||
| ``` | |||
| - `outDir`: Where production files are generated | |||
| - `emptyOutDir`: Cleans the output directory before building | |||
| ### Multiple Entry Points | |||
| ```javascript | |||
| rollupOptions: { | |||
| input: { | |||
| main: '/index.html', | |||
| dashboard: '/pages/dashboard.html', | |||
| login: '/pages/auth/login.html' | |||
| } | |||
| } | |||
| ``` | |||
| Each entry creates a separate HTML file in the build. | |||
| ### Development Server | |||
| ```javascript | |||
| server: { | |||
| port: 3000, | |||
| hot: true, | |||
| open: true, | |||
| host: 'localhost' | |||
| } | |||
| ``` | |||
| ## NPM Scripts | |||
| The `package.json` defines useful scripts: | |||
| ```json | |||
| { | |||
| "scripts": { | |||
| "dev": "vite", | |||
| "build": "vite build", | |||
| "preview": "vite preview", | |||
| "clean": "rm -rf dist", | |||
| "build:analyze": "vite build --analyze", | |||
| "build:watch": "vite build --watch" | |||
| } | |||
| } | |||
| ``` | |||
| ### Script Explanations | |||
| - **`npm run dev`** - Start development server | |||
| - **`npm run build`** - Create production build | |||
| - **`npm run preview`** - Preview production build locally | |||
| - **`npm run clean`** - Remove dist directory | |||
| - **`npm run build:analyze`** - Analyze bundle size | |||
| - **`npm run build:watch`** - Rebuild on file changes | |||
| ## Development Workflow | |||
| ### 1. Starting Development | |||
| ```bash | |||
| npm run dev | |||
| ``` | |||
| This starts the Vite dev server with: | |||
| - Hot Module Replacement (HMR) | |||
| - Fast refresh for styles | |||
| - Error overlay | |||
| - Network access for mobile testing | |||
| ### 2. Making Changes | |||
| When you modify files: | |||
| - **HTML/Handlebars** - Page refreshes automatically | |||
| - **SCSS** - Styles update without refresh | |||
| - **JavaScript** - Modules hot-reload | |||
| - **Assets** - Changes reflect immediately | |||
| ### 3. Adding New Pages | |||
| To add a new page: | |||
| 1. Create the HTML file: | |||
| ```html | |||
| <!-- src/pages/features/new-feature.html --> | |||
| {{> layouts/main title="New Feature"}} | |||
| {{#*inline "content"}} | |||
| <!-- Page content --> | |||
| {{/inline}} | |||
| {{> layouts/base}} | |||
| ``` | |||
| 2. Add to `vite.config.js`: | |||
| ```javascript | |||
| input: { | |||
| 'new-feature': resolve(__dirname, 'src/pages/features/new-feature.html') | |||
| } | |||
| ``` | |||
| 3. The page is now accessible at `/pages/features/new-feature.html` | |||
| ## Production Build | |||
| ### Building for Production | |||
| ```bash | |||
| npm run build | |||
| ``` | |||
| This command: | |||
| 1. Cleans the output directory | |||
| 2. Compiles SCSS to CSS | |||
| 3. Transpiles JavaScript | |||
| 4. Optimizes assets | |||
| 5. Generates HTML files | |||
| 6. Creates source maps | |||
| ### Build Optimizations | |||
| Vite automatically applies these optimizations: | |||
| - **Code Splitting** - Shared code in separate chunks | |||
| - **Tree Shaking** - Removes unused code | |||
| - **Minification** - Compressed HTML, CSS, JS | |||
| - **Asset Optimization** - Compressed images | |||
| - **CSS Extraction** - Separate CSS files | |||
| - **Chunk Hashing** - Cache busting | |||
| ### Build Output | |||
| ``` | |||
| dist/ | |||
| ├── assets/ | |||
| │ ├── index-[hash].css # Main styles | |||
| │ ├── index-[hash].js # Main JavaScript | |||
| │ └── vendor-[hash].js # Vendor libraries | |||
| ├── pages/ | |||
| │ └── [all HTML pages] | |||
| ├── index.html | |||
| └── favicon.ico | |||
| ``` | |||
| ## Environment Variables | |||
| ### Using Environment Variables | |||
| Create a `.env` file: | |||
| ```env | |||
| VITE_APP_NAME=My Dashboard | |||
| VITE_API_URL=https://api.example.com | |||
| VITE_VERSION=1.0.0 | |||
| ``` | |||
| Access in JavaScript: | |||
| ```javascript | |||
| console.log(import.meta.env.VITE_APP_NAME); | |||
| console.log(import.meta.env.VITE_API_URL); | |||
| ``` | |||
| Access in HTML/Handlebars: | |||
| ```html | |||
| <title>{{env.VITE_APP_NAME}}</title> | |||
| ``` | |||
| ### Environment-Specific Builds | |||
| ```bash | |||
| # Development | |||
| npm run dev | |||
| # Production | |||
| npm run build | |||
| # Staging (with .env.staging) | |||
| npm run build -- --mode staging | |||
| ``` | |||
| ## Advanced Configuration | |||
| ### Custom Plugins | |||
| Add plugins to extend Vite functionality: | |||
| ```javascript | |||
| import imagemin from 'vite-plugin-imagemin'; | |||
| export default { | |||
| plugins: [ | |||
| imagemin({ | |||
| gifsicle: { optimizationLevel: 3 }, | |||
| optipng: { optimizationLevel: 7 }, | |||
| mozjpeg: { quality: 75 }, | |||
| svgo: { plugins: [{ name: 'removeViewBox' }] } | |||
| }) | |||
| ] | |||
| } | |||
| ``` | |||
| ### Proxy Configuration | |||
| For API development: | |||
| ```javascript | |||
| server: { | |||
| proxy: { | |||
| '/api': { | |||
| target: 'http://localhost:3001', | |||
| changeOrigin: true, | |||
| rewrite: (path) => path.replace(/^\/api/, '') | |||
| } | |||
| } | |||
| } | |||
| ``` | |||
| ### Build Performance | |||
| Optimize build performance: | |||
| ```javascript | |||
| build: { | |||
| // Increase chunk size warning limit | |||
| chunkSizeWarningLimit: 1000, | |||
| // Optimize dependencies | |||
| commonjsOptions: { | |||
| include: [/node_modules/] | |||
| }, | |||
| // Source maps only for errors | |||
| sourcemap: 'hidden' | |||
| } | |||
| ``` | |||
| ## Troubleshooting | |||
| ### Common Issues | |||
| #### Port Already in Use | |||
| ```bash | |||
| # Use different port | |||
| npm run dev -- --port 3001 | |||
| # Or kill process on port 3000 | |||
| lsof -ti:3000 | xargs kill | |||
| ``` | |||
| #### Build Errors | |||
| ```bash | |||
| # Clear cache | |||
| rm -rf node_modules/.vite | |||
| # Reinstall dependencies | |||
| rm -rf node_modules package-lock.json | |||
| npm install | |||
| ``` | |||
| #### HMR Not Working | |||
| ```javascript | |||
| // Add to vite.config.js | |||
| server: { | |||
| watch: { | |||
| usePolling: true | |||
| } | |||
| } | |||
| ``` | |||
| #### Large Bundle Size | |||
| ```bash | |||
| # Analyze bundle | |||
| npm run build -- --analyze | |||
| # Check visualization at: | |||
| # http://localhost:8888 | |||
| ``` | |||
| ## Deployment Configuration | |||
| ### Static Hosting | |||
| For static hosts (Netlify, Vercel): | |||
| ```javascript | |||
| base: '/', | |||
| build: { | |||
| outDir: 'dist' | |||
| } | |||
| ``` | |||
| ### Subdirectory Deployment | |||
| For subdirectory deployment: | |||
| ```javascript | |||
| base: '/admin/', | |||
| build: { | |||
| outDir: 'dist', | |||
| assetsDir: 'assets' | |||
| } | |||
| ``` | |||
| ### Server Configuration | |||
| Example nginx config: | |||
| ```nginx | |||
| server { | |||
| listen 80; | |||
| server_name example.com; | |||
| root /var/www/concept/dist; | |||
| location / { | |||
| try_files $uri $uri/ /index.html; | |||
| } | |||
| location /assets { | |||
| expires 1y; | |||
| add_header Cache-Control "public, immutable"; | |||
| } | |||
| } | |||
| ``` | |||
| ## Best Practices | |||
| ### Development | |||
| - Use environment variables for configuration | |||
| - Keep `vite.config.js` clean and documented | |||
| - Leverage HMR for faster development | |||
| - Use development tools and browser extensions | |||
| ### Production | |||
| - Always test production builds locally | |||
| - Monitor bundle sizes | |||
| - Enable appropriate caching headers | |||
| - Use CDN for static assets | |||
| - Implement proper error tracking | |||
| ### Performance | |||
| - Lazy load large components | |||
| - Use dynamic imports for code splitting | |||
| - Optimize images before adding | |||
| - Minimize third-party dependencies | |||
| ## Next Steps | |||
| Master the build system with these guides: | |||
| 1. **[Deployment Guide](../deployment/overview.md)** - Deploy to production | |||
| 2. **[Performance Optimization](../advanced/optimization.md)** - Speed up your app | |||
| 3. **[Custom Builds](../advanced/custom-builds.md)** - Advanced configurations | |||
| 4. **[CI/CD Setup](../deployment/ci-cd.md)** - Automated deployments | |||
| --- | |||
| Understanding Vite and the build system empowers you to customize and optimize your development workflow. Happy building! 🚀 | |||
| @ -0,0 +1,312 @@ | |||
| # File Structure | |||
| Understanding the project structure is key to working efficiently with Concept. This guide explains the organization of files and directories. | |||
| ## Project Root Structure | |||
| ``` | |||
| concept-modern/ | |||
| ├── src/ # Source files (development) | |||
| ├── dist/ # Production build output | |||
| ├── public/ # Static public assets | |||
| ├── docs/ # Documentation files | |||
| ├── scripts/ # Build and utility scripts | |||
| ├── node_modules/ # Dependencies (git-ignored) | |||
| ├── .gitignore # Git ignore rules | |||
| ├── package.json # Project metadata and scripts | |||
| ├── package-lock.json # Locked dependency versions | |||
| ├── vite.config.js # Vite configuration | |||
| └── README.md # Project documentation | |||
| ``` | |||
| ## Source Directory Structure | |||
| The `src/` directory contains all development files: | |||
| ``` | |||
| src/ | |||
| ├── assets/ # Static assets | |||
| │ ├── fonts/ # Custom fonts | |||
| │ └── images/ # Images and icons | |||
| ├── config/ # Configuration files | |||
| │ └── navigation.js # Sidebar navigation config | |||
| ├── js/ # JavaScript modules | |||
| │ ├── app.js # Main application entry | |||
| │ ├── components/ # Reusable components | |||
| │ └── pages/ # Page-specific scripts | |||
| ├── pages/ # HTML pages | |||
| │ ├── apps/ # Application pages | |||
| │ ├── auth/ # Authentication pages | |||
| │ ├── dashboards/ # Dashboard variants | |||
| │ ├── ecommerce/ # E-commerce pages | |||
| │ ├── email/ # Email app pages | |||
| │ ├── misc/ # Miscellaneous pages | |||
| │ ├── tables/ # Table examples | |||
| │ └── ui-elements/ # UI component demos | |||
| ├── partials/ # Handlebars partials | |||
| │ ├── components/ # Reusable components | |||
| │ └── layouts/ # Layout partials | |||
| ├── scss/ # Sass stylesheets | |||
| │ ├── components/ # Component styles | |||
| │ ├── layouts/ # Layout styles | |||
| │ ├── pages/ # Page-specific styles | |||
| │ ├── utilities/ # Utility classes | |||
| │ ├── _variables.scss # Sass variables | |||
| │ └── main.scss # Main stylesheet | |||
| └── index.html # Main entry point | |||
| ``` | |||
| ## Key Directories Explained | |||
| ### `/src/assets/` | |||
| Static assets that are processed by Vite: | |||
| - **fonts/** - Custom web fonts (if not using CDN) | |||
| - **images/** - Images, icons, logos | |||
| ``` | |||
| assets/ | |||
| ├── fonts/ | |||
| │ └── inter/ # Inter font files | |||
| └── images/ | |||
| ├── logo.png # Application logo | |||
| ├── avatars/ # User avatars | |||
| └── products/ # Product images | |||
| ``` | |||
| ### `/src/js/` | |||
| JavaScript modules using ES6 syntax: | |||
| ``` | |||
| js/ | |||
| ├── app.js # Main app initialization | |||
| ├── components/ | |||
| │ ├── charts.js # Chart.js wrapper | |||
| │ ├── datatables.js # DataTables setup | |||
| │ ├── sidebar.js # Sidebar functionality | |||
| │ └── tooltips.js # Bootstrap tooltips | |||
| └── pages/ | |||
| ├── dashboard.js # Dashboard-specific code | |||
| ├── calendar.js # Calendar page logic | |||
| └── products.js # Product page logic | |||
| ``` | |||
| ### `/src/pages/` | |||
| All HTML pages organized by feature: | |||
| ``` | |||
| pages/ | |||
| ├── dashboards/ | |||
| │ ├── finance.html # Finance dashboard | |||
| │ ├── sales.html # Sales dashboard | |||
| │ └── influencer.html # Influencer dashboard | |||
| ├── apps/ | |||
| │ ├── calendar.html # Calendar application | |||
| │ └── chat.html # Chat application | |||
| ├── auth/ | |||
| │ ├── login.html # Login page | |||
| │ ├── signup.html # Registration page | |||
| │ └── forgot-password.html # Password reset | |||
| └── ui-elements/ | |||
| ├── buttons.html # Button examples | |||
| ├── cards.html # Card layouts | |||
| └── forms.html # Form elements | |||
| ``` | |||
| ### `/src/partials/` | |||
| Handlebars template partials for reusability: | |||
| ``` | |||
| partials/ | |||
| ├── layouts/ | |||
| │ ├── base.hbs # Base HTML structure | |||
| │ ├── main.hbs # Main layout wrapper | |||
| │ ├── head.hbs # HTML head section | |||
| │ ├── header.hbs # Top navigation bar | |||
| │ ├── sidebar.hbs # Side navigation | |||
| │ ├── footer.hbs # Footer section | |||
| │ └── scripts.hbs # Script includes | |||
| └── components/ | |||
| ├── breadcrumb.hbs # Breadcrumb navigation | |||
| ├── page-header.hbs # Page title section | |||
| └── card.hbs # Reusable card component | |||
| ``` | |||
| ### `/src/scss/` | |||
| Organized Sass files following ITCSS methodology: | |||
| ``` | |||
| scss/ | |||
| ├── _variables.scss # Global variables | |||
| ├── main.scss # Main entry point | |||
| ├── layouts/ | |||
| │ ├── _layout.scss # Overall layout | |||
| │ ├── _sidebar.scss # Sidebar styles | |||
| │ ├── _header.scss # Header styles | |||
| │ └── _footer.scss # Footer styles | |||
| ├── components/ | |||
| │ ├── _buttons.scss # Button styles | |||
| │ ├── _cards.scss # Card styles | |||
| │ ├── _forms.scss # Form styles | |||
| │ └── _tables.scss # Table styles | |||
| ├── pages/ | |||
| │ ├── _dashboard.scss # Dashboard specific | |||
| │ ├── _login.scss # Login page styles | |||
| │ └── _products.scss # Product pages | |||
| └── utilities/ | |||
| ├── _helpers.scss # Helper classes | |||
| └── _animations.scss # Animations | |||
| ``` | |||
| ## File Naming Conventions | |||
| ### HTML Files | |||
| - Use kebab-case: `product-details.html` | |||
| - Group by feature: `pages/ecommerce/products.html` | |||
| ### JavaScript Files | |||
| - Use camelCase for files: `productDetails.js` | |||
| - Use PascalCase for classes: `ProductManager.js` | |||
| - Suffix with type: `product.service.js` | |||
| ### SCSS Files | |||
| - Prefix partials with underscore: `_buttons.scss` | |||
| - Match component names: `_product-card.scss` | |||
| ### Asset Files | |||
| - Use kebab-case: `user-avatar-default.png` | |||
| - Include dimensions: `hero-banner-1920x600.jpg` | |||
| - Be descriptive: `icon-shopping-cart.svg` | |||
| ## Important Files | |||
| ### `vite.config.js` | |||
| Vite build configuration: | |||
| ```javascript | |||
| export default { | |||
| root: 'src', | |||
| build: { | |||
| outDir: '../dist', | |||
| rollupOptions: { | |||
| input: { | |||
| main: '/index.html', | |||
| // Add pages here | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ``` | |||
| ### `package.json` | |||
| Project dependencies and scripts: | |||
| ```json | |||
| { | |||
| "scripts": { | |||
| "dev": "vite", | |||
| "build": "vite build", | |||
| "preview": "vite preview" | |||
| } | |||
| } | |||
| ``` | |||
| ### `/src/config/navigation.js` | |||
| Centralized navigation configuration: | |||
| ```javascript | |||
| export const navigation = [ | |||
| { | |||
| id: 'dashboard', | |||
| label: 'Dashboard', | |||
| icon: 'fa-chart-line', | |||
| submenu: [...] | |||
| } | |||
| ] | |||
| ``` | |||
| ## Adding New Files | |||
| ### Adding a New Page | |||
| 1. Create HTML file in appropriate directory: | |||
| ``` | |||
| src/pages/features/new-feature.html | |||
| ``` | |||
| 2. Add to `vite.config.js`: | |||
| ```javascript | |||
| input: { | |||
| 'new-feature': '/pages/features/new-feature.html' | |||
| } | |||
| ``` | |||
| 3. Create JavaScript if needed: | |||
| ``` | |||
| src/js/pages/new-feature.js | |||
| ``` | |||
| 4. Create SCSS if needed: | |||
| ``` | |||
| src/scss/pages/_new-feature.scss | |||
| ``` | |||
| ### Adding a New Component | |||
| 1. Create component JavaScript: | |||
| ``` | |||
| src/js/components/newComponent.js | |||
| ``` | |||
| 2. Create component styles: | |||
| ``` | |||
| src/scss/components/_new-component.scss | |||
| ``` | |||
| 3. Import in main files: | |||
| ```scss | |||
| // In main.scss | |||
| @import "components/new-component"; | |||
| ``` | |||
| ## Build Output Structure | |||
| After running `npm run build`, the `dist/` directory contains: | |||
| ``` | |||
| dist/ | |||
| ├── assets/ | |||
| │ ├── css/ # Compiled CSS files | |||
| │ ├── js/ # Compiled JS files | |||
| │ └── images/ # Optimized images | |||
| ├── pages/ # All HTML pages | |||
| ├── index.html # Main entry point | |||
| └── [other pages].html # Other built pages | |||
| ``` | |||
| ## Best Practices | |||
| ### Organization | |||
| - Keep related files together | |||
| - Use consistent naming conventions | |||
| - Follow the established structure | |||
| - Document new patterns | |||
| ### Performance | |||
| - Lazy load large components | |||
| - Optimize images before adding | |||
| - Use code splitting for pages | |||
| - Minimize third-party dependencies | |||
| ### Maintenance | |||
| - Remove unused files | |||
| - Keep dependencies updated | |||
| - Document custom modifications | |||
| - Use meaningful commit messages | |||
| ## Next Steps | |||
| Now that you understand the file structure: | |||
| 1. **[Learn About Build Tools](build-tools.md)** - Vite configuration details | |||
| 2. **[Page Structure](../layout/page-structure.md)** - How pages are constructed | |||
| 3. **[Adding Components](../components/creating-components.md)** - Create new components | |||
| 4. **[Customization Guide](../customization/overview.md)** - Modify the template | |||
| --- | |||
| Understanding the file structure is crucial for efficient development. Take time to explore the directories and familiarize yourself with the organization. | |||
| @ -0,0 +1,330 @@ | |||
| # Detailed Installation Guide | |||
| This guide provides comprehensive installation instructions for the Concept admin dashboard template. | |||
| ## System Requirements | |||
| ### Minimum Requirements | |||
| - **Node.js**: 18.0.0 or higher | |||
| - **npm**: 9.0.0 or higher (or yarn 1.22+) | |||
| - **RAM**: 4GB minimum (8GB recommended) | |||
| - **Disk Space**: 500MB free space | |||
| ### Recommended Development Environment | |||
| - **OS**: macOS, Windows 10/11, or Linux | |||
| - **Editor**: VS Code with recommended extensions | |||
| - **Browser**: Chrome or Firefox (latest versions) | |||
| - **Terminal**: Native terminal, iTerm2 (macOS), or Windows Terminal | |||
| ## Installation Methods | |||
| ### Method 1: Using npm (Recommended) | |||
| ```bash | |||
| # Navigate to project directory | |||
| cd concept-modern | |||
| # Install dependencies | |||
| npm install | |||
| # Start development server | |||
| npm run dev | |||
| ``` | |||
| ### Method 2: Using Yarn | |||
| ```bash | |||
| # Install Yarn globally if not already installed | |||
| npm install -g yarn | |||
| # Navigate to project directory | |||
| cd concept-modern | |||
| # Install dependencies | |||
| yarn install | |||
| # Start development server | |||
| yarn dev | |||
| ``` | |||
| ### Method 3: Using pnpm (Faster Alternative) | |||
| ```bash | |||
| # Install pnpm globally | |||
| npm install -g pnpm | |||
| # Navigate to project directory | |||
| cd concept-modern | |||
| # Install dependencies | |||
| pnpm install | |||
| # Start development server | |||
| pnpm dev | |||
| ``` | |||
| ## Detailed Setup Steps | |||
| ### 1. Verify Prerequisites | |||
| First, check that you have the required tools installed: | |||
| ```bash | |||
| # Check Node.js version | |||
| node --version | |||
| # Expected: v18.0.0 or higher | |||
| # Check npm version | |||
| npm --version | |||
| # Expected: 9.0.0 or higher | |||
| # Check Git (optional but recommended) | |||
| git --version | |||
| # Expected: Any recent version | |||
| ``` | |||
| ### 2. Download or Clone the Project | |||
| **Option A: Download ZIP** | |||
| 1. Download the Concept template ZIP file | |||
| 2. Extract to your preferred location | |||
| 3. Open terminal in the extracted folder | |||
| **Option B: Clone via Git** | |||
| ```bash | |||
| # Clone the repository | |||
| git clone https://github.com/yourusername/concept-modern.git | |||
| # Enter the directory | |||
| cd concept-modern | |||
| ``` | |||
| ### 3. Install Dependencies | |||
| ```bash | |||
| # Install all dependencies | |||
| npm install | |||
| # If you encounter permission errors on macOS/Linux | |||
| sudo npm install | |||
| # For Windows, run terminal as Administrator | |||
| ``` | |||
| ### 4. Environment Configuration (Optional) | |||
| Create a `.env` file for environment-specific settings: | |||
| ```bash | |||
| # Create .env file | |||
| touch .env | |||
| # Add environment variables | |||
| echo "VITE_APP_TITLE=My Dashboard" >> .env | |||
| echo "VITE_API_URL=http://localhost:3001" >> .env | |||
| ``` | |||
| ### 5. Start Development Server | |||
| ```bash | |||
| # Start with default settings | |||
| npm run dev | |||
| # Start with specific host/port | |||
| npm run dev -- --host 0.0.0.0 --port 3001 | |||
| # Start with HTTPS (requires certificate) | |||
| npm run dev -- --https | |||
| ``` | |||
| ## VS Code Setup (Recommended) | |||
| ### Install Recommended Extensions | |||
| Create `.vscode/extensions.json`: | |||
| ```json | |||
| { | |||
| "recommendations": [ | |||
| "dbaeumer.vscode-eslint", | |||
| "esbenp.prettier-vscode", | |||
| "stylelint.vscode-stylelint", | |||
| "bradlc.vscode-tailwindcss", | |||
| "ritwickdey.liveserver", | |||
| "formulahendry.auto-rename-tag", | |||
| "vue.volar" | |||
| ] | |||
| } | |||
| ``` | |||
| ### Configure VS Code Settings | |||
| Create `.vscode/settings.json`: | |||
| ```json | |||
| { | |||
| "editor.formatOnSave": true, | |||
| "editor.defaultFormatter": "esbenp.prettier-vscode", | |||
| "editor.codeActionsOnSave": { | |||
| "source.fixAll.eslint": true | |||
| }, | |||
| "scss.validate": false, | |||
| "css.validate": false, | |||
| "stylelint.validate": ["css", "scss"] | |||
| } | |||
| ``` | |||
| ## Build for Production | |||
| ### Standard Build | |||
| ```bash | |||
| # Create production build | |||
| npm run build | |||
| # Files will be in dist/ directory | |||
| ls -la dist/ | |||
| ``` | |||
| ### Build with Analysis | |||
| ```bash | |||
| # Build and analyze bundle size | |||
| npm run build -- --analyze | |||
| # Opens bundle analyzer in browser | |||
| ``` | |||
| ### Preview Production Build | |||
| ```bash | |||
| # Build and preview | |||
| npm run build | |||
| npm run preview | |||
| # Preview will run on http://localhost:4173 | |||
| ``` | |||
| ## Deployment | |||
| ### Deploy to Netlify | |||
| ```bash | |||
| # Install Netlify CLI | |||
| npm install -g netlify-cli | |||
| # Build project | |||
| npm run build | |||
| # Deploy to Netlify | |||
| netlify deploy --prod --dir=dist | |||
| ``` | |||
| ### Deploy to Vercel | |||
| ```bash | |||
| # Install Vercel CLI | |||
| npm install -g vercel | |||
| # Build and deploy | |||
| vercel | |||
| ``` | |||
| ### Deploy to GitHub Pages | |||
| ```bash | |||
| # Install gh-pages | |||
| npm install --save-dev gh-pages | |||
| # Add deploy script to package.json | |||
| "scripts": { | |||
| "deploy": "npm run build && gh-pages -d dist" | |||
| } | |||
| # Deploy | |||
| npm run deploy | |||
| ``` | |||
| ## Troubleshooting | |||
| ### Common Issues and Solutions | |||
| #### 1. EACCES Permission Errors | |||
| **macOS/Linux:** | |||
| ```bash | |||
| # Fix npm permissions | |||
| sudo chown -R $(whoami) ~/.npm | |||
| sudo chown -R $(whoami) /usr/local/lib/node_modules | |||
| ``` | |||
| **Windows:** | |||
| - Run terminal as Administrator | |||
| - Or install Node.js to a directory you own | |||
| #### 2. Module Not Found Errors | |||
| ```bash | |||
| # Clear cache and reinstall | |||
| rm -rf node_modules package-lock.json | |||
| npm cache clean --force | |||
| npm install | |||
| ``` | |||
| #### 3. Port Already in Use | |||
| ```bash | |||
| # Find process using port 3000 | |||
| # macOS/Linux | |||
| lsof -i :3000 | |||
| # Windows | |||
| netstat -ano | findstr :3000 | |||
| # Kill the process or use different port | |||
| npm run dev -- --port 3001 | |||
| ``` | |||
| #### 4. Vite Build Errors | |||
| ```bash | |||
| # Clear Vite cache | |||
| rm -rf node_modules/.vite | |||
| npm run build | |||
| ``` | |||
| #### 5. SCSS Compilation Errors | |||
| ```bash | |||
| # Rebuild node-sass | |||
| npm rebuild sass | |||
| # Or reinstall | |||
| npm uninstall sass | |||
| npm install sass | |||
| ``` | |||
| ### Getting More Help | |||
| If you're still having issues: | |||
| 1. Check the [GitHub Issues](https://github.com/yourusername/concept-modern/issues) | |||
| 2. Search for error messages | |||
| 3. Create a new issue with: | |||
| - Error message | |||
| - Node/npm versions | |||
| - Operating system | |||
| - Steps to reproduce | |||
| ## Next Steps | |||
| ✅ Installation complete! Here's what to do next: | |||
| 1. **[Explore the File Structure](file-structure.md)** - Understand project organization | |||
| 2. **[Learn About Build Tools](build-tools.md)** - Master Vite configuration | |||
| 3. **[Start Customizing](../customization/overview.md)** - Make it your own | |||
| 4. **[Add Your First Page](../layout/page-structure.md)** - Extend functionality | |||
| --- | |||
| Congratulations on setting up Concept! 🎉 | |||
| @ -0,0 +1,126 @@ | |||
| # Introduction to Concept | |||
| Welcome to Concept - a modern, feature-rich admin dashboard template built with Bootstrap 5 and powered by Vite. | |||
| ## What is Concept? | |||
| Concept is a professional admin dashboard template designed to accelerate the development of web applications. Whether you're building a CRM, CMS, admin panel, or analytics dashboard, Concept provides all the components and pages you need to get started quickly. | |||
| ## Why Choose Concept? | |||
| ### 🚀 Modern Technology Stack | |||
| - **Bootstrap 5.3.7** - The latest version of the world's most popular CSS framework | |||
| - **Vite 7** - Lightning-fast build tool with instant hot module replacement | |||
| - **No jQuery** - Pure vanilla JavaScript for better performance | |||
| - **ES6 Modules** - Modern JavaScript architecture | |||
| - **Sass** - Powerful CSS preprocessing | |||
| ### 💎 Rich Feature Set | |||
| - **4 Dashboard Variants** - E-commerce, Finance, Sales, and Influencer | |||
| - **50+ UI Components** - Everything from buttons to complex data tables | |||
| - **Built-in Apps** - Email client, chat, calendar, and more | |||
| - **Authentication Pages** - Login, register, password reset | |||
| - **Responsive Design** - Works perfectly on all devices | |||
| ### 🛠️ Developer Friendly | |||
| - **Clean Code Structure** - Well-organized and documented | |||
| - **Handlebars Templating** - Reusable components and layouts | |||
| - **Hot Reload** - See changes instantly during development | |||
| - **Modular Architecture** - Easy to extend and customize | |||
| - **Comprehensive Documentation** - Everything you need to know | |||
| ## Template Variants | |||
| ### Dashboard Pages | |||
| 1. **E-commerce Dashboard** | |||
| - Revenue analytics | |||
| - Order management | |||
| - Product performance | |||
| - Customer insights | |||
| 2. **Finance Dashboard** | |||
| - Financial metrics | |||
| - Transaction charts | |||
| - Portfolio overview | |||
| - Budget tracking | |||
| 3. **Sales Dashboard** | |||
| - Sales funnel | |||
| - Team performance | |||
| - Revenue forecasting | |||
| - Lead tracking | |||
| 4. **Influencer Dashboard** | |||
| - Social media metrics | |||
| - Engagement analytics | |||
| - Campaign performance | |||
| - Audience insights | |||
| ### Pre-built Applications | |||
| - **Email Client** - Full-featured inbox, compose, and email management | |||
| - **Chat Application** - Real-time messaging interface | |||
| - **Calendar** - Event management with multiple views | |||
| - **User Management** - User lists, profiles, and permissions | |||
| - **E-commerce** - Product listings, details, and checkout | |||
| ## What's Included | |||
| ### Core Files | |||
| ``` | |||
| concept-modern/ | |||
| ├── src/ # Source files | |||
| ├── dist/ # Production build | |||
| ├── docs/ # Documentation | |||
| ├── package.json # Dependencies | |||
| └── vite.config.js # Build configuration | |||
| ``` | |||
| ### UI Components | |||
| - Alerts & Notifications | |||
| - Buttons & Button Groups | |||
| - Cards & Panels | |||
| - Forms & Validation | |||
| - Tables & Data Grids | |||
| - Charts & Graphs | |||
| - Modals & Dialogs | |||
| - Navigation & Menus | |||
| ### Plugins & Libraries | |||
| - **Chart.js** - Beautiful charts and graphs | |||
| - **DataTables** - Advanced table functionality | |||
| - **FullCalendar** - Feature-rich calendar | |||
| - **Tom Select** - Enhanced select boxes | |||
| - **Quill** - Rich text editor | |||
| - **Font Awesome 7** - Comprehensive icon set | |||
| ## Community & Support | |||
| ### Getting Help | |||
| - **Documentation** - Comprehensive guides in the `docs/` folder | |||
| - **GitHub Issues** - Report bugs and request features | |||
| - **Community Forum** - Connect with other developers | |||
| - **Email Support** - Direct support for license holders | |||
| ### Contributing | |||
| We welcome contributions! Whether it's: | |||
| - Reporting bugs | |||
| - Suggesting new features | |||
| - Improving documentation | |||
| - Submitting pull requests | |||
| ## License | |||
| Concept is available under the MIT License, making it free for both personal and commercial projects. | |||
| ## Next Steps | |||
| Ready to get started? Here's what to do next: | |||
| 1. **[Quick Start Guide](quick-start.md)** - Get up and running in 5 minutes | |||
| 2. **[Installation](installation.md)** - Detailed setup instructions | |||
| 3. **[File Structure](file-structure.md)** - Understand the project organization | |||
| 4. **[Customization](../customization/overview.md)** - Make it your own | |||
| --- | |||
| Thank you for choosing Concept! We're excited to see what you'll build with it. | |||
| @ -0,0 +1,189 @@ | |||
| # Quick Start Guide | |||
| Get your Concept dashboard up and running in just 5 minutes! | |||
| ## Prerequisites | |||
| Before you begin, ensure you have the following installed: | |||
| - **Node.js** (version 18 or higher) - [Download Node.js](https://nodejs.org/) | |||
| - **npm** (comes with Node.js) or **yarn** | |||
| - A code editor (we recommend [VS Code](https://code.visualstudio.com/)) | |||
| - A modern web browser | |||
| To check if you have Node.js installed, run: | |||
| ```bash | |||
| node --version | |||
| # Should output: v18.x.x or higher | |||
| npm --version | |||
| # Should output: 9.x.x or higher | |||
| ``` | |||
| ## 🚀 5-Minute Setup | |||
| ### Step 1: Get the Files | |||
| **Option A: Download** | |||
| 1. Download the Concept template zip file | |||
| 2. Extract it to your desired location | |||
| 3. Open the folder in your terminal | |||
| **Option B: Clone from Git** | |||
| ```bash | |||
| git clone https://github.com/yourusername/concept-modern.git | |||
| cd concept-modern | |||
| ``` | |||
| ### Step 2: Install Dependencies | |||
| Run the following command in your project directory: | |||
| ```bash | |||
| npm install | |||
| ``` | |||
| This will install all required packages including Bootstrap, Vite, and other dependencies. | |||
| ### Step 3: Start Development Server | |||
| ```bash | |||
| npm run dev | |||
| ``` | |||
| You should see output like: | |||
| ``` | |||
| VITE v7.0.6 ready in 325 ms | |||
| ➜ Local: http://localhost:3000/ | |||
| ➜ Network: http://192.168.1.100:3000/ | |||
| ➜ press h + enter to show help | |||
| ``` | |||
| ### Step 4: Open in Browser | |||
| Navigate to [http://localhost:3000](http://localhost:3000) in your browser. | |||
| 🎉 **Congratulations!** You should now see the Concept dashboard running locally. | |||
| ## Common Commands | |||
| ### Development | |||
| ```bash | |||
| # Start dev server with hot reload | |||
| npm run dev | |||
| # Start on a different port | |||
| npm run dev -- --port 3001 | |||
| ``` | |||
| ### Building for Production | |||
| ```bash | |||
| # Create optimized production build | |||
| npm run build | |||
| # Preview production build locally | |||
| npm run preview | |||
| ``` | |||
| ### Other Commands | |||
| ```bash | |||
| # Clean build directory | |||
| npm run clean | |||
| # Check for dependency updates | |||
| npm outdated | |||
| # Update dependencies | |||
| npm update | |||
| ``` | |||
| ## First Steps After Setup | |||
| ### 1. Explore the Dashboard | |||
| - Click through different dashboard variants | |||
| - Try the sidebar navigation | |||
| - Test responsive behavior | |||
| ### 2. Check Out Components | |||
| - Visit `/pages/ui-elements/general.html` | |||
| - Explore form elements | |||
| - View table examples | |||
| ### 3. Try the Apps | |||
| - Open the email client | |||
| - Test the chat interface | |||
| - Browse the calendar | |||
| ### 4. Customize Your First Page | |||
| 1. Open `src/pages/misc/blank-page.html` | |||
| 2. Add your content | |||
| 3. Save and see instant updates | |||
| ## Project Structure Overview | |||
| ``` | |||
| concept-modern/ | |||
| ├── src/ | |||
| │ ├── index.html # Main dashboard | |||
| │ ├── pages/ # All HTML pages | |||
| │ ├── js/ # JavaScript files | |||
| │ ├── scss/ # Styles | |||
| │ └── assets/ # Images & fonts | |||
| ├── package.json # Dependencies | |||
| └── vite.config.js # Build config | |||
| ``` | |||
| ## Troubleshooting Quick Fixes | |||
| ### Port Already in Use | |||
| ```bash | |||
| # Use a different port | |||
| npm run dev -- --port 3001 | |||
| ``` | |||
| ### Dependencies Not Installing | |||
| ```bash | |||
| # Clear npm cache | |||
| npm cache clean --force | |||
| # Delete node_modules and reinstall | |||
| rm -rf node_modules package-lock.json | |||
| npm install | |||
| ``` | |||
| ### Build Errors | |||
| ```bash | |||
| # Clear dist folder | |||
| npm run clean | |||
| # Rebuild | |||
| npm run build | |||
| ``` | |||
| ### Vite Not Starting | |||
| Make sure you're in the correct directory: | |||
| ```bash | |||
| pwd | |||
| # Should show: /path/to/concept-modern | |||
| ``` | |||
| ## What's Next? | |||
| Now that you have Concept running: | |||
| 1. **[Read the Installation Guide](installation.md)** - For detailed setup options | |||
| 2. **[Understand File Structure](file-structure.md)** - Learn where everything is | |||
| 3. **[Start Customizing](../customization/overview.md)** - Make it yours | |||
| 4. **[Add New Pages](../layout/page-structure.md)** - Extend functionality | |||
| ## Need Help? | |||
| - 📚 Check the full documentation in the `docs/` folder | |||
| - 🐛 Report issues on GitHub | |||
| - 💬 Join our community forum | |||
| - 📧 Email support for license holders | |||
| --- | |||
| Happy coding! 🚀 | |||