1import { doViewTransition } from '../scripts/view-transitions.js'; 2 3// 4// Updates the theme when a theme selector changes 5// 6async function updateTheme(value, isInitialLoad = false) { 7 const body = document.body; 8 9 // Get brand, palette, and theme name from the selected option, falling back to the saved values on pages without a 10 // theme selector so visiting them doesn't reset the user's choice 11 const themeSelector = document.querySelector('.theme-selector'); 12 const selectedOption = themeSelector?.querySelector(`wa-dropdown-item[value="${value}"]`); 13 let brand = selectedOption?.getAttribute('data-brand') || localStorage.getItem('brand') || 'blue'; 14 let palette = selectedOption?.getAttribute('data-palette') || localStorage.getItem('palette') || 'default'; 15 let themeName = selectedOption?.textContent.trim() || 'Unknown'; 16 17 if (!isInitialLoad) { 18 // Disable tooltip during theme transition 19 const tooltip = document.querySelector('#theme-tooltip'); 20 if (tooltip) { 21 tooltip.disabled = true; 22 } 23 24 // Add fade-out class 25 body.classList.add('theme-transitioning'); 26 27 // Wait for fade-out to complete 28 await new Promise(resolve => { 29 const handleTransitionEnd = event => { 30 if (event.target === body && event.propertyName === 'opacity') { 31 body.removeEventListener('transitionend', handleTransitionEnd); 32 resolve(); 33 } 34 }; 35 body.addEventListener('transitionend', handleTransitionEnd); 36 }); 37 } 38 39 // Handle site theme vs regular theme 40 let href = `/dist/styles/themes/${value}.css`; 41 42 if (document.querySelector('wa-page')?.dataset.pageType === 'site') { 43 brand = 'orange'; 44 href = `/assets/styles/theme-site.css`; 45 palette = 'default'; 46 value = 'site'; 47 } else { 48 localStorage.setItem('brand', brand); 49 localStorage.setItem('palette', palette); 50 localStorage.setItem('theme', value); 51 setCookie({ name: 'webawesome_brand', value: brand });
52 setCookie({ name: 'webawesome_palette', value: palette }); 53 setCookie({ name: 'webawesome_theme', value }); 54 } 55 56 // A page can pin its brand with data-page-brand on <wa-page> (e.g. Create stays orange). This gets applied after 57 // persistence so the pin never overwrites the user's saved brand choice. 58 const pageBrand = document.querySelector('wa-page')?.dataset.pageBrand; 59 if (pageBrand) { 60 brand = pageBrand; 61 } 62 63 // Update theme classes 64 const htmlElement = document.documentElement; 65 const classesToRemove = Array.from(htmlElement.classList).filter( 66 className => 67 className.startsWith('wa-theme-') || className.startsWith('wa-brand-') || className.startsWith('wa-palette-'), 68 ); 69 const themeStylesheet = document.getElementById('theme-stylesheet'); 70 71 await doViewTransition(() => { 72 // Update the theme 73 if (themeStylesheet) { 74 themeStylesheet.href = href; 75 } 76 77 htmlElement.classList.remove(...classesToRemove); 78 79 // Add the new theme, brand, and palette classes 80 htmlElement.classList.add(`wa-theme-${value}`); 81 htmlElement.classList.add(`wa-brand-${brand}`); 82 htmlElement.classList.add(`wa-palette-${palette}`); 83 84 // Sync all theme selectors 85 document.querySelectorAll('.theme-selector').forEach(el => { 86 el.value = value; 87 el.setAttribute('value', value); 88 }); 89 90 // Update tooltip content to reflect the new theme 91 const tooltip = document.querySelector('#theme-tooltip'); 92 if (tooltip) { 93 tooltip.textContent = `${themeName} Theme`; 94 } 95 }); 96 97 if (!isInitialLoad) { 98 // Remove transition class and re-enable tooltip after view transition completes 99 body.classList.remove('theme-transitioning'); 100 101 const tooltip = document.querySelector('#theme-tooltip'); 102 if (tooltip) { 103 tooltip.disabled = false; 104 } 105 } 106} 107 108// Handle changes 109document.addEventListener('input', event => { 110 if (event.target.matches('.theme-selector')) { 111 updateTheme(event.target.value); 112 } 113}); 114 115// Initialize 116function initializeTheme() { 117 const savedTheme = localStorage.getItem('theme') || 'default'; 118 updateTheme(savedTheme, true); 119} 120 121initializeTheme(); 122 123document.addEventListener('turbo:render', initializeTheme);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.