UNPKG

@zeix/ui-element

Version:

UIElement - minimal reactive framework based on Web Components

112 lines (110 loc) 23.4 kB
<tab-list> <menu> <li><button type="button" aria-pressed="true">TypeScript</button></li> </menu> <details open> <summary> <div class="summary">TS</div> </summary> <code-block language="ts" copy-success="Copied!" copy-error="Error trying to copy to clipboard!"> <p class="meta"> <span class="file">media-context.ts</span> <span class="language">ts</span> </p> <pre class="shiki monokai" style="background-color:#272822;color:#F8F8F2" tabindex="0"><code><span class="line"><span style="color:#F92672">import</span><span style="color:#F8F8F2"> { UIElement, </span><span style="color:#F92672">type</span><span style="color:#F8F8F2"> Context } </span><span style="color:#F92672">from</span><span style="color:#E6DB74"> '../../../'</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F">/* === Provided Context Keys === */</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic">const</span><span style="color:#F8F8F2"> MEDIA_MOTION </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'media-motion'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic">const</span><span style="color:#F8F8F2"> MEDIA_THEME </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'media-theme'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic">const</span><span style="color:#F8F8F2"> MEDIA_VIEWPORT </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'media-viewport'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic">const</span><span style="color:#F8F8F2"> MEDIA_ORIENTATION </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'media-orientation'</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F">/* === Pure Functions === */</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic">const</span><span style="color:#A6E22E"> parseBreakpoint</span><span style="color:#F92672"> =</span><span style="color:#F8F8F2"> (</span><span style="color:#FD971F;font-style:italic">value</span><span style="color:#F92672">:</span><span style="color:#66D9EF;font-style:italic"> string</span><span style="color:#F92672"> |</span><span style="color:#66D9EF;font-style:italic"> null</span><span style="color:#F8F8F2">, </span><span style="color:#FD971F;font-style:italic">fallback</span><span style="color:#F92672">:</span><span style="color:#66D9EF;font-style:italic"> string</span><span style="color:#F8F8F2">) </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> attr </span><span style="color:#F92672">=</span><span style="color:#F8F8F2"> value?.</span><span style="color:#A6E22E">trim</span><span style="color:#F8F8F2">()</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (</span><span style="color:#F92672">!</span><span style="color:#F8F8F2">attr) </span><span style="color:#F92672">return</span><span style="color:#F8F8F2"> fallback</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> unit </span><span style="color:#F92672">=</span><span style="color:#F8F8F2"> attr.</span><span style="color:#A6E22E">match</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">/em</span><span style="color:#F92672">$</span><span style="color:#E6DB74">/</span><span style="color:#F8F8F2">) </span><span style="color:#F92672">?</span><span style="color:#E6DB74"> 'em'</span><span style="color:#F92672"> :</span><span style="color:#E6DB74"> 'px'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> v </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> parseFloat</span><span style="color:#F8F8F2">(attr)</span></span> <span class="line"><span style="color:#F92672"> return</span><span style="color:#F8F8F2"> Number.</span><span style="color:#A6E22E">isFinite</span><span style="color:#F8F8F2">(v) </span><span style="color:#F92672">?</span><span style="color:#F8F8F2"> v </span><span style="color:#F92672">+</span><span style="color:#F8F8F2"> unit </span><span style="color:#F92672">:</span><span style="color:#F8F8F2"> fallback</span></span> <span class="line"><span style="color:#F8F8F2">}</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F">/* === Class Definition === */</span></span> <span class="line"></span> <span class="line"><span style="color:#F92672">export</span><span style="color:#66D9EF;font-style:italic"> class</span><span> </span><span style="color:#A6E22E;text-decoration:underline">MediaContext</span><span style="color:#F92672"> extends</span><span style="color:#A6E22E"> UIElement</span><span style="color:#F8F8F2">&#x3C;{</span></span> <span class="line"><span style="color:#E6DB74"> 'media-motion'</span><span style="color:#F92672">:</span><span style="color:#66D9EF;font-style:italic"> boolean</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#E6DB74"> 'media-theme'</span><span style="color:#F92672">:</span><span style="color:#66D9EF;font-style:italic"> string</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#E6DB74"> 'media-viewport'</span><span style="color:#F92672">:</span><span style="color:#66D9EF;font-style:italic"> string</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#E6DB74"> 'media-orientation'</span><span style="color:#F92672">:</span><span style="color:#66D9EF;font-style:italic"> string</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#F8F8F2">}> {</span></span> <span class="line"><span style="color:#F92672"> static</span><span style="color:#F92672"> readonly</span><span style="color:#F8F8F2"> localName </span><span style="color:#F92672">=</span><span style="color:#E6DB74">'media-context'</span></span> <span class="line"><span style="color:#F92672"> static</span><span style="color:#F8F8F2"> providedContexts </span><span style="color:#F92672">=</span><span style="color:#F8F8F2"> [</span></span> <span class="line"><span style="color:#F8F8F2"> MEDIA_MOTION </span><span style="color:#F92672">as</span><span> </span><span style="color:#A6E22E;text-decoration:underline">Context</span><span style="color:#F8F8F2">&#x3C;</span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">, </span><span style="color:#66D9EF;font-style:italic">boolean</span><span style="color:#F8F8F2">>,</span></span> <span class="line"><span style="color:#F8F8F2"> MEDIA_THEME </span><span style="color:#F92672">as</span><span> </span><span style="color:#A6E22E;text-decoration:underline">Context</span><span style="color:#F8F8F2">&#x3C;</span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">, </span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">>,</span></span> <span class="line"><span style="color:#F8F8F2"> MEDIA_VIEWPORT </span><span style="color:#F92672">as</span><span> </span><span style="color:#A6E22E;text-decoration:underline">Context</span><span style="color:#F8F8F2">&#x3C;</span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">, </span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">>,</span></span> <span class="line"><span style="color:#F8F8F2"> MEDIA_ORIENTATION </span><span style="color:#F92672">as</span><span> </span><span style="color:#A6E22E;text-decoration:underline">Context</span><span style="color:#F8F8F2">&#x3C;</span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">, </span><span style="color:#66D9EF;font-style:italic">string</span><span style="color:#F8F8F2">>,</span></span> <span class="line"><span style="color:#F8F8F2"> ]</span></span> <span class="line"></span> <span class="line"><span style="color:#A6E22E"> connectedCallback</span><span style="color:#F8F8F2">() {</span></span> <span class="line"><span style="color:#FD971F"> super</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">connectedCallback</span><span style="color:#F8F8F2">()</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> THEME_LIGHT </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'light'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> THEME_DARK </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'dark'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> VIEWPORT_XS </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'xs'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> VIEWPORT_SM </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'sm'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> VIEWPORT_MD </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'md'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> VIEWPORT_LG </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'lg'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> VIEWPORT_XL </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'xl'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> ORIENTATION_LANDSCAPE </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'landscape'</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> ORIENTATION_PORTRAIT </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> 'portrait'</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#A6E22E"> getBreakpoints</span><span style="color:#F92672"> =</span><span style="color:#F8F8F2"> () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> ({</span></span> <span class="line"><span style="color:#F8F8F2"> sm: </span><span style="color:#A6E22E">parseBreakpoint</span><span style="color:#F8F8F2">(</span><span style="color:#FD971F">this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">getAttribute</span><span style="color:#F8F8F2">(VIEWPORT_SM), </span><span style="color:#E6DB74">'32em'</span><span style="color:#F8F8F2">),</span></span> <span class="line"><span style="color:#F8F8F2"> md: </span><span style="color:#A6E22E">parseBreakpoint</span><span style="color:#F8F8F2">(</span><span style="color:#FD971F">this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">getAttribute</span><span style="color:#F8F8F2">(VIEWPORT_MD), </span><span style="color:#E6DB74">'48em'</span><span style="color:#F8F8F2">),</span></span> <span class="line"><span style="color:#F8F8F2"> lg: </span><span style="color:#A6E22E">parseBreakpoint</span><span style="color:#F8F8F2">(</span><span style="color:#FD971F">this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">getAttribute</span><span style="color:#F8F8F2">(VIEWPORT_LG), </span><span style="color:#E6DB74">'72em'</span><span style="color:#F8F8F2">),</span></span> <span class="line"><span style="color:#F8F8F2"> xl: </span><span style="color:#A6E22E">parseBreakpoint</span><span style="color:#F8F8F2">(</span><span style="color:#FD971F">this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">getAttribute</span><span style="color:#F8F8F2">(VIEWPORT_XL), </span><span style="color:#E6DB74">'108em'</span><span style="color:#F8F8F2">),</span></span> <span class="line"><span style="color:#F8F8F2"> })</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> breakpoints </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> getBreakpoints</span><span style="color:#F8F8F2">()</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> reducedMotion </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'(prefers-reduced-motion: reduce)'</span><span style="color:#F8F8F2">)</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> colorScheme </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'(prefers-color-scheme: dark)'</span><span style="color:#F8F8F2">)</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> screenSmall </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">`(min-width: </span><span style="color:#F92672">${</span><span style="color:#F8F8F2">breakpoints.sm</span><span style="color:#F92672">}</span><span style="color:#E6DB74">)`</span><span style="color:#F8F8F2">)</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> screenMedium </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">`(min-width: </span><span style="color:#F92672">${</span><span style="color:#F8F8F2">breakpoints.md</span><span style="color:#F92672">}</span><span style="color:#E6DB74">)`</span><span style="color:#F8F8F2">)</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> screenLarge </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">`(min-width: </span><span style="color:#F92672">${</span><span style="color:#F8F8F2">breakpoints.lg</span><span style="color:#F92672">}</span><span style="color:#E6DB74">)`</span><span style="color:#F8F8F2">)</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> screenXLarge </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">`(min-width: </span><span style="color:#F92672">${</span><span style="color:#F8F8F2">breakpoints.xl</span><span style="color:#F92672">}</span><span style="color:#E6DB74">)`</span><span style="color:#F8F8F2">)</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> screenOrientation </span><span style="color:#F92672">=</span><span style="color:#A6E22E"> matchMedia</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'(orientation: landscape)'</span><span style="color:#F8F8F2">)</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#A6E22E"> getViewport</span><span style="color:#F92672"> =</span><span style="color:#F8F8F2"> () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (screenXLarge.matches) </span><span style="color:#F92672">return</span><span style="color:#F8F8F2"> VIEWPORT_XL</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (screenLarge.matches) </span><span style="color:#F92672">return</span><span style="color:#F8F8F2"> VIEWPORT_LG</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (screenMedium.matches) </span><span style="color:#F92672">return</span><span style="color:#F8F8F2"> VIEWPORT_MD</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (screenSmall.matches) </span><span style="color:#F92672">return</span><span style="color:#F8F8F2"> VIEWPORT_SM</span></span> <span class="line"><span style="color:#F92672"> return</span><span style="color:#F8F8F2"> VIEWPORT_XS</span></span> <span class="line"><span style="color:#F8F8F2"> }</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F"> // set initial values</span></span> <span class="line"><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_MOTION, reducedMotion.matches)</span></span> <span class="line"><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_THEME, colorScheme.matches </span><span style="color:#F92672">?</span><span style="color:#F8F8F2"> THEME_DARK </span><span style="color:#F92672">:</span><span style="color:#F8F8F2"> THEME_LIGHT)</span></span> <span class="line"><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_VIEWPORT, </span><span style="color:#A6E22E">getViewport</span><span style="color:#F8F8F2">())</span></span> <span class="line"><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_ORIENTATION, screenOrientation.matches </span><span style="color:#F92672">?</span><span style="color:#F8F8F2"> ORIENTATION_LANDSCAPE </span><span style="color:#F92672">:</span><span style="color:#F8F8F2"> ORIENTATION_PORTRAIT)</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F"> // event listeners</span></span> <span class="line"><span style="color:#F8F8F2"> reducedMotion.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, </span><span style="color:#FD971F;font-style:italic">e</span><span style="color:#66D9EF;font-style:italic"> =></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_MOTION, e.matches))</span></span> <span class="line"><span style="color:#F8F8F2"> colorScheme.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, </span><span style="color:#FD971F;font-style:italic">e</span><span style="color:#66D9EF;font-style:italic"> =></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_THEME, e.matches </span><span style="color:#F92672">?</span><span style="color:#F8F8F2"> THEME_DARK </span><span style="color:#F92672">:</span><span style="color:#F8F8F2"> THEME_LIGHT))</span></span> <span class="line"><span style="color:#F8F8F2"> screenSmall.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_VIEWPORT, </span><span style="color:#A6E22E">getViewport</span><span style="color:#F8F8F2">()))</span></span> <span class="line"><span style="color:#F8F8F2"> screenMedium.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_VIEWPORT, </span><span style="color:#A6E22E">getViewport</span><span style="color:#F8F8F2">()))</span></span> <span class="line"><span style="color:#F8F8F2"> screenLarge.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_VIEWPORT, </span><span style="color:#A6E22E">getViewport</span><span style="color:#F8F8F2">()))</span></span> <span class="line"><span style="color:#F8F8F2"> screenXLarge.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_VIEWPORT, </span><span style="color:#A6E22E">getViewport</span><span style="color:#F8F8F2">()))</span></span> <span class="line"><span style="color:#F8F8F2"> screenOrientation.</span><span style="color:#A6E22E">addEventListener</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'change'</span><span style="color:#F8F8F2">, </span><span style="color:#FD971F;font-style:italic">e</span><span style="color:#66D9EF;font-style:italic"> =></span><span style="color:#FD971F"> this</span><span style="color:#F8F8F2">.</span><span style="color:#A6E22E">set</span><span style="color:#F8F8F2">(MEDIA_THEME, e.matches </span><span style="color:#F92672">?</span><span style="color:#F8F8F2"> ORIENTATION_LANDSCAPE </span><span style="color:#F92672">:</span><span style="color:#F8F8F2"> ORIENTATION_PORTRAIT))</span></span> <span class="line"><span style="color:#F8F8F2"> }</span></span> <span class="line"><span style="color:#F8F8F2">}</span></span> <span class="line"><span style="color:#F8F8F2">MediaContext.</span><span style="color:#A6E22E">define</span><span style="color:#F8F8F2">()</span></span></code></pre> <input-button class="copy"> <button type="button" class="secondary small"> <span class="label">Copy</span> </button> </input-button> </code-block> </details> </tab-list>