@zeix/ui-element
Version:
UIElement - minimal reactive framework based on Web Components
112 lines (110 loc) • 23.4 kB
HTML
<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"><{</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"><</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"><</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"><</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"><</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>