# EasyStream Design System - Integration Snippets Quick copy-paste snippets to integrate the new design system into EasyStream templates. ## Table of Contents 1. [HTML Head Updates](#html-head-updates) 2. [Skip Links](#skip-links) 3. [Theme Switcher UI](#theme-switcher-ui) 4. [Accessibility Improvements](#accessibility-improvements) 5. [Responsive Components](#responsive-components) --- ## HTML Head Updates ### Add to Smarty Template Headers **For frontend templates** ([f_templates/tpl_frontend/tpl_head_min.tpl](f_templates/tpl_frontend/tpl_head_min.tpl)): ```smarty {* Add after existing CSS includes *} ``` ### Add to Footer Scripts **For frontend templates** ([f_templates/tpl_frontend/tpl_footerjs_min.tpl](f_templates/tpl_frontend/tpl_footerjs_min.tpl)): ```smarty {* Add before closing body tag *} ``` --- ## Skip Links ### Add to Body Start **Add to** ([f_templates/tpl_frontend/tpl_body.tpl](f_templates/tpl_frontend/tpl_body.tpl:1)) at the very beginning: ```smarty {* Skip links for accessibility *} {* Rest of body content *} ``` ### Add Main Content ID **Update main wrapper** in [f_templates/tpl_frontend/tpl_body_main.tpl](f_templates/tpl_frontend/tpl_body_main.tpl): ```smarty
{* Your main content *}
``` --- ## Theme Switcher UI ### Option 1: Add to Header Navigation **Add to** [f_templates/tpl_frontend/tpl_header/tpl_headernav_yt.tpl](f_templates/tpl_frontend/tpl_header/tpl_headernav_yt.tpl): ```smarty {* Add to header navigation area *}
{* Theme toggle button *} {* Existing notification bell, user menu, etc. *}
``` ### Option 2: Full Theme Picker Modal Create new template: `f_templates/tpl_frontend/tpl_theme_picker.tpl` ```smarty {* Theme Picker Modal *} ``` --- ## Accessibility Improvements ### Form Labels **Before:** ```html ``` **After:** ```html ``` ### Image Alt Text **Before:** ```smarty ``` **After:** ```smarty {$video.title|escape} - Thumbnail ``` ### Button Accessibility **Before:** ```html ``` **After:** ```html ``` ### Heading Hierarchy **Before:** ```html
Featured Videos
My Video
``` **After:** ```html

Featured Videos

My Video

``` ### ARIA Landmarks **Add to templates:** ```smarty
{* Header content *}
{* Main content *}
``` --- ## Responsive Components ### Video Grid **Before:** ```smarty
{foreach from=$videos item=video}
{* Video thumbnail *}
{/foreach}
``` **After:** ```smarty
{foreach from=$videos item=video}
{$video.title|escape} - Thumbnail

{$video.title}

{$video.views} views {$video.date}

{/foreach}
``` ### Responsive Container **Before:** ```html
{* Content *}
``` **After:** ```html
{* Content auto-sizes with padding *}
``` ### Flex Layout **Before:** ```html
{$title}
{$actions}
``` **After:** ```html
{$title}
{$actions}
``` ### Responsive Text **Before:** ```html

{$title}

``` **After:** ```html

{$title}

``` ### Responsive Spacing **Before:** ```html
{* Content *}
``` **After:** ```html
{* Content *}
``` ### Card Component **New pattern:** ```html

Card Title

{* Card content *}
``` ### Alert Messages **Before:** ```smarty {if $error_message}
{$error_message}
{/if} ``` **After:** ```smarty {if $error_message} {/if} {if $success_message} {/if} ``` --- ## JavaScript Enhancements ### Theme Switcher Events ```javascript // Listen for theme changes document.addEventListener('easystream:theme-change', (e) => { console.log('Theme changed:', e.detail); // Update other components if needed }); // Programmatically change theme window.themeSwitcher.toggleMode(); // Toggle light/dark window.themeSwitcher.setColor('red'); // Change color // Get current theme const theme = window.themeSwitcher.getCurrentTheme(); console.log(theme); // { mode: 'dark', color: 'blue', ... } ``` ### Service Worker Updates ```javascript // Update service worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js?v=2') .then(reg => { // Check for updates reg.update(); // Listen for updates reg.addEventListener('updatefound', () => { const newWorker = reg.installing; newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { // New version available if (confirm('New version available! Reload to update?')) { window.location.reload(); } } }); }); }); } ``` ### Offline Detection ```javascript // Detect online/offline window.addEventListener('online', () => { console.log('Back online!'); // Show success message showNotification('You are back online', 'success'); }); window.addEventListener('offline', () => { console.log('Gone offline'); // Show warning message showNotification('You are offline. Some features may be unavailable.', 'warning'); }); function showNotification(message, type) { const alert = document.createElement('div'); alert.className = `alert alert-${type}`; alert.textContent = message; alert.role = 'alert'; document.body.appendChild(alert); setTimeout(() => alert.remove(), 5000); } ``` --- ## Testing Snippets ### Check Accessibility ```javascript // Check for images without alt text const imagesWithoutAlt = document.querySelectorAll('img:not([alt])'); console.log('Images missing alt text:', imagesWithoutAlt.length); // Check for buttons without labels const buttonsWithoutLabel = document.querySelectorAll('button:not([aria-label]):not(:has(.sr-only))'); console.log('Buttons missing labels:', buttonsWithoutLabel.length); // Check heading hierarchy const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); headings.forEach(h => console.log(h.tagName, h.textContent.substring(0, 50))); ``` ### Check Contrast Ratios ```javascript // Check text contrast (simplified) function checkContrast(element) { const style = getComputedStyle(element); const color = style.color; const bgColor = style.backgroundColor; console.log(`Element: ${element.tagName}`, { color, bgColor }); } // Check all text elements document.querySelectorAll('p, h1, h2, h3, h4, h5, h6, a, button, span').forEach(checkContrast); ``` ### Test Keyboard Navigation ```javascript // Highlight focusable elements document.querySelectorAll('a, button, input, select, textarea, [tabindex]').forEach(el => { el.style.outline = '2px solid red'; }); // Tab order test let tabIndex = 0; document.addEventListener('focus', (e) => { console.log(`Tab ${++tabIndex}:`, e.target); }, true); ``` --- ## Common Patterns ### Modal Dialog ```html ``` ### Dropdown Menu ```html ``` ### Loading Spinner ```html
Loading...
``` ### Breadcrumbs ```html ``` --- ## Quick Reference ### Class Names Cheat Sheet **Spacing:** - `m-xs`, `m-sm`, `m-md`, `m-lg` - Margins - `p-xs`, `p-sm`, `p-md`, `p-lg` - Padding **Typography:** - `text-xs`, `text-sm`, `text-md`, `text-lg`, `text-xl` - Font sizes - `font-light`, `font-normal`, `font-medium`, `font-bold` - Font weights **Layout:** - `flex`, `flex-col`, `flex-wrap` - Flexbox - `grid`, `grid-cols-{n}` - Grid - `container` - Responsive container **Display:** - `hidden`, `block`, `flex` - Display - `xs:hidden`, `md:block` - Responsive display **Colors:** - `text-primary`, `text-secondary` - Text colors - `bg-primary`, `bg-secondary` - Background colors **Borders:** - `rounded-sm`, `rounded-md`, `rounded-lg`, `rounded-full` - Border radius **Shadows:** - `shadow-sm`, `shadow-md`, `shadow-lg` - Box shadows **Accessibility:** - `sr-only` - Screen reader only - `touch-target` - Minimum touch size - `focus-visible` - Focus indicator --- ## Migration Checklist - [ ] Include new CSS files in templates - [ ] Include theme-switcher.js - [ ] Add skip links to body - [ ] Add main content ID - [ ] Update navigation with theme toggle - [ ] Replace inline styles with utility classes - [ ] Add alt text to all images - [ ] Add ARIA labels to buttons - [ ] Add labels to form inputs - [ ] Fix heading hierarchy - [ ] Add ARIA landmarks - [ ] Test keyboard navigation - [ ] Test with screen reader - [ ] Test on mobile devices - [ ] Test all theme combinations - [ ] Run Lighthouse audit --- **Next Steps:** See [DESIGN_SYSTEM_GUIDE.md](DESIGN_SYSTEM_GUIDE.md) for complete documentation.