# Component Documentation This guide covers all the UI components available in the Metis Admin Template. ## Table of Contents - [Layout Components](#layout-components) - [Navigation Components](#navigation-components) - [Form Components](#form-components) - [Data Display Components](#data-display-components) - [Feedback Components](#feedback-components) - [Chart Components](#chart-components) --- ## Layout Components ### Sidebar The sidebar provides navigation and uses Bootstrap's collapse for submenus. ```html ``` **Submenu with Collapse:** ```html ``` #### SidebarManager All sidebar toggle behavior is handled by the `SidebarManager` class (`scripts/components/sidebar.js`). It is initialized automatically on every page — no inline scripts are needed. **Desktop behavior (>= 992px):** - Clicking the hamburger button toggles between full sidebar (280px) and mini sidebar (70px) - State is saved to `localStorage` and restored on page load - The `sidebar-collapsed` class is added to `#admin-wrapper` **Mobile behavior (< 992px):** - Sidebar is hidden off-screen by default (`transform: translateX(-100%)`) - Clicking the hamburger slides the sidebar in as an overlay with a backdrop - Closing methods: backdrop click, Escape key, or hamburger button - Background scroll is locked while the sidebar is open **Backdrop element:** Each page should include a `.sidebar-backdrop` div inside `#admin-wrapper`. If missing, `SidebarManager` creates one automatically: ```html
``` ### Header The header contains the brand, hamburger toggle, search, and user controls. ```html
``` The hamburger button is placed right after the brand in the HTML flow. On desktop (>= 992px), it is absolutely positioned at the right edge of the sidebar. On mobile, it stays in normal flow within the navbar. The `data-sidebar-toggle` attribute is what `SidebarManager` listens for — no other click handlers should be attached to this button. ### Header Dropdowns Notification and profile dropdown menus use `position: absolute` to overlay properly on all screen sizes. Bootstrap's default dropdown positioning is overridden in `components/_navigation.scss` to prevent dropdowns from pushing page content. ### Cards Standard Bootstrap 5 card component with custom styling. ```html
Card Title
``` **Notes:** - Cards have `border-width: 0` and use `box-shadow` for elevation - On mobile (< 992px), cards use compact padding and reduced margins for better use of screen space - Card headers and footers also adapt with smaller font sizes and tighter spacing on mobile --- ## Navigation Components ### Breadcrumbs ```html ``` ### Tabs ```html
Content 1
Content 2
``` ### Pagination ```html ``` --- ## Form Components ### Text Inputs ```html
We'll never share your email.
``` ### Select ```html
``` ### Checkboxes & Radios ```html
``` ### Switch ```html
``` --- ## Data Display Components ### Tables ```html
Name Email Status Actions
John Doe john@example.com Active
``` **Table Variants:** - `.table-striped` - Alternating row colors - `.table-bordered` - Borders on all sides - `.table-hover` - Hover effect on rows - `.table-sm` - Compact table ### Badges ```html Primary Success Warning Danger Info Pill ``` ### Progress Bars ```html
75%
``` ### List Groups ```html ``` --- ## Feedback Components ### Alerts ```html ``` ### Toast Notifications (SweetAlert2) The template uses a `NotificationManager` class that wraps SweetAlert2: ```javascript // Access via the global app instance window.AdminApp.notificationManager.success('Operation completed!'); window.AdminApp.notificationManager.error('Something went wrong'); window.AdminApp.notificationManager.warning('Please check your input'); window.AdminApp.notificationManager.info('New update available'); ``` **Direct SweetAlert2 usage:** ```javascript import Swal from 'sweetalert2'; // Success toast Swal.fire({ icon: 'success', title: 'Success!', text: 'Operation completed successfully.', toast: true, position: 'top-end', showConfirmButton: false, timer: 3000 }); // Confirmation dialog Swal.fire({ title: 'Are you sure?', text: "You won't be able to revert this!", icon: 'warning', showCancelButton: true, confirmButtonText: 'Yes, delete it!' }).then((result) => { if (result.isConfirmed) { // Handle deletion } }); ``` ### Modals ```html ``` ### Tooltips Tooltips are automatically initialized by `main.js`: ```html ``` --- ## Chart Components ### ApexCharts Integration ```javascript import ApexCharts from 'apexcharts'; const options = { chart: { type: 'line', height: 350 }, series: [{ name: 'Sales', data: [30, 40, 35, 50, 49, 60, 70] }], xaxis: { categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] } }; const chart = new ApexCharts(document.querySelector('#chart'), options); chart.render(); ``` ### Bar Chart with ApexCharts The template ships **only ApexCharts** as of v3.4.0 — Chart.js was removed. Render a bar chart: ```javascript import ApexCharts from 'apexcharts'; const options = { chart: { type: 'bar', height: 280, toolbar: { show: false } }, series: [{ name: '# of Votes', data: [12, 19, 3, 5, 2, 3] }], xaxis: { categories: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'] }, colors: ['#6366f1'], plotOptions: { bar: { borderRadius: 6, columnWidth: '55%' } }, dataLabels: { enabled: false } }; // IMPORTANT: ApexCharts mounts into a
, not . //
const chart = new ApexCharts(document.querySelector('#myChart'), options); chart.render(); // Always destroy charts when the host component unmounts to avoid leaks: // chart.destroy(); ``` --- ## Alpine.js Components ### Built-in Components The template includes these Alpine.js components registered in `main.js`: **searchComponent** - Global search functionality. As of v3.4.0, each page registers its own `searchComponent` via the shared factory rather than redefining the same shell. From a page component: ```javascript import Alpine from 'alpinejs'; import { createSearchComponent } from '../utils/search-component.js'; document.addEventListener('alpine:init', () => { Alpine.data('searchComponent', createSearchComponent({ minLength: 2, // default delayMs: 200, // simulated debounce getResults(query) { const q = query.toLowerCase(); return [ { title: 'Dashboard', url: '/', type: 'page' }, // … ].filter((item) => item.title.toLowerCase().includes(q)); }, })); }); ``` Markup is unchanged: ```html
``` **themeSwitch** - Dark/light mode toggle: ```html
``` **statsCounter** - Animated counter: ```html
``` --- ## Icon Usage ### Bootstrap Icons (Subset) ```html ``` > **Note (v3.4.0):** The build ships a CSS subset of Bootstrap Icons containing only the ~158 icons actually referenced in the project, rather than all ~1,800. If you add an icon class that isn't in the subset, the icon won't render. Add the rule to `src-modern/styles/scss/components/_bootstrap-icons-subset.scss` or regenerate the file from `bootstrap-icons/font/bootstrap-icons.json`. The font file itself is still the full set, so glyphs are immediately available once a CSS rule is added. ### Font Awesome Font Awesome was removed in v3.4.0 — it was declared but never actually imported. Bootstrap Icons covers everything in the demo. If you need Font Awesome: ```bash npm install @fortawesome/fontawesome-free ``` then `@import "@fortawesome/fontawesome-free/css/all.min.css";` in `main.scss`. --- ## Best Practices 1. **Use semantic HTML** - Use appropriate elements for accessibility 2. **Leverage Bootstrap 5 utilities** - Use utility classes instead of custom CSS 3. **Use Alpine.js for interactivity** - Keep JavaScript simple and declarative 4. **Mobile-first approach** - Design for mobile, then scale up 5. **Accessibility** - Include ARIA labels and support keyboard navigation 6. **Use the page data attribute** - Set `data-page` on body for page-specific JS 7. **No inline sidebar scripts** - All sidebar toggle logic goes through `SidebarManager`; duplicate handlers cause desktop toggle to cancel out 8. **Consistent breakpoint** - Use `992px` / `991.98px` (`lg`) as the single mobile/desktop breakpoint throughout the template --- For more examples, see the live demo pages in `src-modern/`.